帧差法——动态检测——统计车流量
帧差法原理
帧间差分法是一种通过对视频图像序列的连续两帧图像做差分运算获取运动目标轮廓的方法。当监控场景中出现异常目标运动时,相邻两帧图像之间会出现较为明显的差别,两帧相减,求得图像对应位置像素值差的绝对值,判断其是否大于某一阈值,进而分析视频或图像序列的物体运动特性。
实现流程
实现效果
动态检测函数代码
Mat MoveDetect(Mat frame1, Mat frame2) {
Mat result = frame2.clone();
Mat gray1, gray2;
cvtColor(frame1, gray1, CV_BGR2GRAY);
cvtColor(frame2, gray2, CV_BGR2GRAY);
Mat diff;
absdiff(gray1, gray2, diff);//两幅图做差
imshow("absdiss", diff);
threshold(diff, diff, 25, 255, CV_THRESH_BINARY);//二值化diff
Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));//返回指定形状与尺寸得结构元素
Mat element2 = getStructuringElement(MORPH_RECT, Size(19, 19));
erode(diff, diff, element);//腐蚀函数
medianBlur(diff, diff, 3);//中值滤波
dilate(diff, diff, element2);//膨胀函数
vector<vector<Point>> contours;
vector<Vec4i> hierarcy;
findContours(diff, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));//查找轮廓
vector<vector<Point>>contours_poly(contours.size());
vector<Rect> boundRect(contours.size()); //定义外接矩形集合
int x0 = 0, y0 = 0, w0 = 0, h0 = 0;
for (int i = 0; i<contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);//对图像轮廓点进行多边形拟合:轮廓点组成的点集,输出的多边形点集,精度(即两个轮廓点之间的距离),输出多边形是否封闭
boundRect[i] = boundingRect(Mat(contours_poly[i]));
if (boundRect[i].width>90 && boundRect[i].width<180 && boundRect[i].height>90 && boundRect[i].height<180) {//轮廓筛选 (90 180)
x0 = boundRect[i].x;
y0 = boundRect[i].y;
w0 = boundRect[i].width;
h0 = boundRect[i].height;
rectangle(result, Point(x0, y0), Point(x0 + w0, y0 + h0), Scalar(0, 255, 0), 2, 8, 0);
if ((y0 + h0 / 2 + 1) >= 198 && (y0 + h0 / 2 - 1) <= 202) {//经过这条线(区间),车辆数量+1
CarNum++;
}
}
line(result, Point(0, 200), Point(720, 200), Scalar(0, 0, 255), 1, 8);//画红线
Point org(0, 35);
putText(result, "CarNum=" + intToString(CarNum), org, CV_FONT_HERSHEY_SIMPLEX, 0.8f, Scalar(0, 255, 0), 2);
}
return result;
}
完整代码及实验使用视频请到资源处下载
链接: https://download.csdn.net/download/weixin_46958585/12708964.