0

我正在尝试找出 2 张图像的区别。

场景:假设我有 2 张图像,一张是背景,另一张是背景前面的人,我想将两张图像相减,得到人的位置,即程序可以检测人站在哪里,并将减去的图像作为输出。

我设法想出的代码是从相机中获取两张图像并重新调整它们的大小,并将两张图像都转换为灰度。我想知道这之后该怎么做。我检查了 OpenCV 提供的减法函数,但它以数组作为输入,所以我不知道如何进行。

我写的代码是:

cap>>frame; //gets the first image
cv::cvtColor(frame,frame,CV_RGB2GRAY); //converts it to gray scale
cv::resize(frame,frame,Size(30,30));  //re-sizes it

cap>>frame2;//gets the second image
cv::cvtColor(frame2,frame2,CV_RGB2GRAY); //converts it to gray scale
cv::resize(frame2,frame2,Size(30,30)); //re-sizes it

现在我是否只需使用减法函数,例如:

cv::subtract(frame_gray,frame,frame);

还是我先应用一些过滤器然后使用减法功能?

4

2 回答 2

1

正如其他人所注意到的那样,这是一个棘手的问题:很容易想出一个有时会奏效的 hack,很难想出一个在大部分时间都可以在最少人为干预的情况下工作的解决方案。此外,如果您可以严格控制背景的材质和照明,则更容易做到。专业应用被称为“chromakeying”(特别是在电视行业)、“bluescreening”、“matting”或“traveling matte”(在电影摄影中)、“背景去除”在计算机视觉中。

消光准均匀背景的开创性工作是多年前由Petro Vlahos完成的。其基本算法的专利已经过期,所以你可以带着他们去城里(并找到各种质量的开源实现)。毋庸置疑,IANAL,请做好专利主题的功课。

消除更复杂的背景仍然是一个活跃的研究领域,尤其是在没有 3D 信息可用的情况下。您可能想查看几篇 MS Research 近期发表的研究论文(A. Criminisi 在该领域做了一些工作)。

于 2012-07-10T12:23:56.397 回答
0

使用减法是不合适的,因为它可能会导致某些值变为负数,并且只有在您尝试查看是否存在差异时才会起作用(布尔值真/假)。

如果您需要获取不同的像素,您应该逐像素进行比较 - 例如:

int rows = frame.rows;
int cols = frame.cols;
cv::Mat diffImage = cv::Mat::zeros(rows, cols, CV_8UC1);
for(int i = 0; i < rows; ++i)
{
    for(int j = 0; j < cols; ++j)
    {

        if(frame.at<uchar>(i,j) != frame2.at<uchar>(i,j))
            diffImage.at<uchar>(i, j) = 255;
    }
}

现在,您可以显示或保存 diffImage。所有不同的像素都将是白色,而相似的像素将是黑色

于 2012-07-10T10:30:13.070 回答