继上次对两张图片进行检测后,这次对一个段视频进行检测,方法是把第一帧图片作为背景图片,之后的图片依次与改图进行减法处理,然后把不同位置的坐标计算出来,继而把不同的部分显示到原图上。与之对应的另外一种方法是第一次从视频中取出两张图,两张图片进行减法处理之后,保存第二张图,之后每次取出一张图与上一张图做减法处理之后保存,这样每张图都与前面一张图进行比较。这里采用了第一种方法,第二种方法会在之后的博客中接写出并与第一种方法进行比较。
方法一代码如下:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include "opencv2/opencv.hpp"
using namespace cv;
#include <iostream>
using namespace std;
void circle(Mat background, Mat frame);
int main()
{
//VideoCapture video(0);
VideoCapture video("bike.mp4");
if (!video.isOpened()) //对video进行异常检测
{
cout << "video open error!" << endl;
return 0;
}
Mat frame;//存储帧
Mat background;//存储背景图像
double framePosition;
double FPS = video.get(CV_CAP_PROP_FPS);//获取FPS
while (1)
{
video >> frame;//读帧进frame
//imshow("frame", frame);//展示这一帧
framePosition = video.get(CV_CAP_PROP_POS_FRAMES);//获取帧位置(第几帧)
//cout << "framePosition: " << framePosition << endl;
cout << framePosition << endl;
if (framePosition == 1.0) { //将第一帧作为背景图像
background = frame.clone();
}
circle(background, frame);//循环相减
waitKey(30);
}
//if (waitKey(1000.0 / FPS) == 27)//按原FPS显示
//{
// cout << "ESC退出!" << endl;
//}
return 0;
}
void circle(Mat background, Mat frame)
{
Mat diff;//用diff来存储差图
diff.create(frame.size(), frame.type());
absdiff(background, frame, diff);//减
Mat diff_thresh = frame.clone();
//对差值图dif进行阈值化处理
cvtColor(diff, diff, CV_BGR2GRAY);
threshold(diff, diff, 50, 255, CV_THRESH_BINARY);
// 查找轮廓并绘制轮廓
vector<vector<Point>> contours;//contours被定义成二维浮点型向量,用来存储找到的边界的(x,y)坐标。
vector<Vec4i> hierarchy;
findContours(diff, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
drawContours(diff_thresh, contours, -1, Scalar(0, 255, 0), 1, 8);//在dif_thresh上绘制轮廓
//7.查找正外接矩形
int width = 0;
int height = 0;
int x = 0;
int y = 0;
vector<Rect> boundRect(contours.size());
for (int i = 0; i < contours.size(); i++)
{
boundRect[i] = boundingRect(Mat(contours[i]));
//2获得正外接矩形的左上角坐标及宽高
width = boundRect[i].width;
height = boundRect[i].height;
x = boundRect[i].x;
y = boundRect[i].y;
rectangle(diff_thresh, boundRect[i], Scalar(0, 255, 0), 2);//在dif_thresh上绘制正外接矩形
}
//显示图片
imshow("差图", diff_thresh);
}
结果并不是很满意,存在很多干扰,可能是算法不够好,会在之后慢慢改进,这里只能一步一步来。