学习内容:
差值法检测移动物体学习产出:
1、视频的基本参数
视频实际上也是由若干图片以一定的帧率叠加在一起而形成的,其中,我们可以通过get函数获得视频的相关参数,例如
int fps = capture.get(CAP_PROP_FPS);//视频的帧率
int width = capture.get(CAP_PROP_FRAME_WIDTH);//视频的宽度
int height = capture.get(CAP_PROP_FRAME_HEIGHT);//视频的高度
int num_of_frames = capture.get(CAP_PROP_FRAME_COUNT);//视频的总帧数
2、差值函数
这里我们用到absdiff函数,其函数参数结构如下
void cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );
第三个参数即为两数组之间的差值
3、threshold函数
threshold 方法是通过遍历灰度图中各个像素点,将图像信息二值化,处理过后的图片只有二种色值
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
第三个参数,double类型的thresh,阈值的具体值
第四个参数,double类型的maxval,当第五个参数阈值类型type取THRESH_BINARY 或THRESH_BINARY_INV阈值类型时的最大值
第五个参数,int类型的type,阈值类型
type | 含义 |
---|---|
cv2.THRESH_BINARY | 超过阈值部分取maxval(最大值),否则取0 |
cv2.THRESH_BINARY_INV | THRESH_BINARY的反转 |
cv2.THRESH_TRUNC | 大于阈值部分设为阈值,否则不变 |
cv2.THRESH_TOZERO | 大于阈值部分不改变,否则设为0 |
cv2.THRESH_TOZERO_INV | THRESH_TOZERO的反转 |
但这里是需要多传入一个参数( flag):THRESH_OTSU,加在第五个参数后,这是为了一副双峰图像自动根据其直方图可以自动计算出一个阈值,具体参考threshold实现全局和OTSU阈值二值化
4、morphologyEx函数
void morphologyEx( InputArray src, OutputArray dst, int op,
InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue() )
这个函数很复杂,简单来说就是系列的膨胀腐蚀的组合
常用参数如下:
●MORPH_ERODE(腐蚀)
跟erode(腐蚀)函数效果一样
●MORPH_DILATE(膨胀)
跟dilate(膨胀)函数效果一样
●MORPH_OPEN(开)
其实内部就是进行了先腐蚀后膨胀的操作。
●MORPH_CLOSE(闭)
其实内部就是进行了先膨胀后腐蚀的操作。
5、差值法检测移动物体实例
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
VideoCapture capture("resources/1.mp4");
if (!capture.isOpened()) { cout << "请确认视频文件是否正确" << endl; return -1; }
int fps = capture.get(CAP_PROP_FPS);
int width = capture.get(CAP_PROP_FRAME_WIDTH);
int height = capture.get(CAP_PROP_FRAME_HEIGHT);
int num_of_frames = capture.get(CAP_PROP_FRAME_COUNT);
cout << "视频宽度:" << width << "视频高度:" << height << "视频帧率:" << fps << "视频总帧数:" << num_of_frames << endl;
Mat preFrame, preGray;
capture >> preFrame;
cvtColor(preFrame, preGray, CV_BGR2GRAY);
//对图像进行高斯滤波
GaussianBlur(preGray, preGray, Size(0, 0), 15);
Mat binary, frame, gray;
//形态学操作模板
Mat k = getStructuringElement(MORPH_RECT, Size(9, 9), Point(-1, -1));
while (true)
{
if (!capture.read(frame)){ break;}
cvtColor(frame, gray, COLOR_BGR2GRAY);
GaussianBlur(gray, gray, Size(0, 0), 15);
//计算当前帧和前一帧差值的绝对值
absdiff(gray, preGray, binary);
//对结果二值化进行开运算,减少噪声干扰
threshold(binary, binary, 10, 255, THRESH_BINARY | THRESH_OTSU);
morphologyEx(binary, binary, MORPH_OPEN, k);
imshow("input", frame);
imshow("output", binary);
//如果注释下一行代码,则程序表示固定背景的差值法
gray.copyTo(preGray);
char c = waitKey(5);
if (c == 27) { break;}
}
waitKey(0);
return 0;
}