目标检测中最简单的方法是利用减除背景的方式,先采集一张背景图像,然后在目标检测的过程中减去之前的背景得到目标物体,这种方法容易受到光照、摄像机位置等因素的影响,效果并不理想。
这里采用帧差法(frame differencing),利用前后帧画面的差别取得新出现的物体。
过程如下:
diff1 = |nextFrame - curFrame|
diff2 = |curFrame - preFrame|
output = |diff1 and diff2|
最后一步采用and操作能使得结果中噪声影响较小,效果更稳定。
代码如下:
void main()
{
Mat frame;
Mat preFrame, nextFrame, frame1, frame2, output;
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return;
}
cap >> preFrame;
cap >> frame;
cvtColor(preFrame, preFrame, CV_BGR2GRAY);
cvtColor(frame, frame, CV_BGR2GRAY);
namedWindow("res");
namedWindow("show");
imshow("show", frame);
while (true)
{
// Capture the current frame
cap >> nextFrame;
cvtColor(nextFrame, nextFrame, CV_BGR2GRAY);
imshow("show", frame);
absdiff(nextFrame, frame, frame1);
absdiff(frame, preFrame, frame2);
bitwise_and(frame1, frame2, output);
output = frameDiff(preFrame, frame, nextFrame);
imshow("res", output);
if (waitKey(30) >= 0)break;
preFrame = frame;
frame = nextFrame;
}
cap.release();
// Close all windows
destroyAllWindows();
}
Mat frameDiff(Mat prevFrame, Mat curFrame, Mat nextFrame)
{
Mat diffFrames1, diffFrames2, output;
// Compute absolute difference between current frame and the nextframe
absdiff(nextFrame, curFrame, diffFrames1);
// Compute absolute difference between current frame and the previous frame
absdiff(curFrame, prevFrame, diffFrames2);
// Bitwise "AnD" operation between the above two diff images
bitwise_and(diffFrames1, diffFrames2, output);
return output;
}
效果图如下: