OpenCV4入门147:帧差图absdiff()

索引地址:系列索引

如果摄像机是固定的,那么我们可以认为场景(背景)大多数情况下是不变的,而只有前景(被跟踪的目标)会运动,这样就可以建立背景模型。通过比较当前帧和背景模型,就能轻松地跟踪目标运动情况了。这里,最容易想到的比较方式就是当前帧减去背景模型了

函数声明

1
2
3
4
void cv::absdiff 	( 	InputArray  	src1,
InputArray src2,
OutputArray dst
)
  • 输入1
  • 输入2
  • 输出

计算两个数组之间或数组与标量之间的每元素绝对差。

可以简单的理解为结果是画面中动的部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// FRAME DIFFERENCING

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <sstream>

using namespace cv;
using namespace std;

Mat frameDiff(Mat prevFrame, Mat curFrame, Mat nextFrame)
{
Mat diffFrames1, diffFrames2, output;

// Compute absolute difference between current frame and the next frame
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;
}

Mat getFrame(VideoCapture cap, float scalingFactor)
{
//float scalingFactor = 0.5;
Mat frame, output;

// Capture the current frame
cap >> frame;

// Resize the frame
resize(frame, frame, Size(), scalingFactor, scalingFactor, INTER_AREA);

// Convert to grayscale
cvtColor(frame, output, CV_BGR2GRAY);

return output;
}

int main(int argc, char* argv[])
{
Mat frame, prevFrame, curFrame, nextFrame;
char ch;

// Create the capture object
// 0 -> input arg that specifies it should take the input from the webcam
VideoCapture cap(0);

// If you cannot open the webcam, stop the execution!
if( !cap.isOpened() )
return -1;

//create GUI windows
namedWindow("Frame");

// Scaling factor to resize the input frames from the webcam
float scalingFactor = 0.75;

prevFrame = getFrame(cap, scalingFactor);
curFrame = getFrame(cap, scalingFactor);
nextFrame = getFrame(cap, scalingFactor);

// Iterate until the user presses the Esc key
while(true)
{
// Show the object movement
imshow("Object Movement", frameDiff(prevFrame, curFrame, nextFrame));

// Update the variables and grab the next frame
prevFrame = curFrame;
curFrame = nextFrame;
nextFrame = getFrame(cap, scalingFactor);

// Get the keyboard input and check if it's 'Esc'
// 27 -> ASCII value of 'Esc' key
ch = waitKey( 30 );
if (ch == 27) {
break;
}
}

// Release the video capture object
cap.release();

// Close all windows
destroyAllWindows();

return 1;
}

效果为

absdiff

使用的是笔记本摄像头,只有我头在动,所以结果中只有脸部分