【发布时间】:2019-10-18 14:44:06
【问题描述】:
我面临的困难是现场背景减法。尝试了很多方法,但无济于事。我要完成的任务是删除相机拍摄的背景图像,以及相机正在流式传输的实时视频。
absdiff 是我目前用于背景减法的方法,因为它似乎产生了迄今为止最好的结果。
我的代码如下所示:
while(1)
{
capture>>imagef;
imshow("image with foreground", imagef);
imagef.convertTo(imagef, CV_8UC3);
//cvtColor(imagef, imagef, CV_BGR2GRAY);
absdiff(imagef,imageb, imageFinal); //imageb is the background image
imshow("after diff", imageFinal);
//cvtColor(imageFinal, imageFinal, CV_BGR2GRAY); //change to grayscale
threshold(imageFinal, imageFinal, 20, 255, CV_THRESH_BINARY); // change to grayscale
imshow("Camera Window",imageFinal); //show video
int key = cvWaitKey(10); //Capture Keyboard stroke
if (char(key) == 27)
{
break; //If you hit ESC key loop will break.
}
}
然而,无论摄像头视频是否引入了新图像,此代码都会返回一个空白图像。
请注意,如果我取消注释cvtColor,在处理之前将imagef(视频帧)和imageb(静态图像)都转换为灰度,我可以检索新图像之间的差异,但是会丢失信息由于强度相似,但如果我降低阈值,视频会有水平移动线(在明亮的条件下,因此我可以将其设置得太低)。
我想问一下 absdiff 是否只适用于灰度图像?如果它也适用于 BGR 图像,那我哪里出错了?
【问题讨论】:
-
imageb 永远不会被初始化?
-
@berak,确实如此。
capture>> imageb;这行放在while循环之前。 -
这是因为我不希望背景是“活的”或变化的。我希望它保持不变。
-
@berak,已经解决了。显然,我不能使用
capture>>imageb;。我必须使用capture>>imagef;后跟imagef.copyTo(imageb);... 这很奇怪。你知道为什么吗?两者都是不同的Mat,为什么我需要添加额外的行来制作imageb? -
不,捕捉中的垫子没有不同,但都一样(它们指向捕捉中的静态内存) - 所以你必须在捕获(这也可以解释为什么它与灰度转换一起工作,但并非没有 - 转换复制到不同的内存位置)
标签: opencv image-processing computer-vision