博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
opencv学习之路(37)、运动物体检测(二)
阅读量:5281 次
发布时间:2019-06-14

本文共 7685 字,大约阅读时间需要 25 分钟。

一、运动物体轮廓椭圆拟合及中心

1 #include "opencv2/opencv.hpp" 2 #include
3 using namespace std; 4 using namespace cv; 5 6 Mat MoveDetect(Mat frame1, Mat frame2) 7 { 8 Mat result = frame2.clone(); 9 Mat gray1, gray2;10 cvtColor(frame1, gray1, CV_BGR2GRAY);11 cvtColor(frame2, gray2, CV_BGR2GRAY);12 13 Mat diff;14 absdiff(gray1, gray2, diff);15 imshow("absdiss", diff);16 threshold(diff, diff, 45, 255, CV_THRESH_BINARY);17 imshow("threshold", diff);18 19 Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));20 Mat element2 = getStructuringElement(MORPH_RECT, Size(25, 25));21 erode(diff, diff, element);22 imshow("erode", diff);23 24 dilate(diff, diff, element2);25 imshow("dilate", diff);26 27 vector
> contours;28 vector
hierarcy;29 //画椭圆及中心30 findContours(diff, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);31 cout<<"num="<
<
box(contours.size());33 for(int i=0; i
>frame;54 if(frame.empty())55 break;56 else{ 57 count++;58 if(count==1)59 background = frame.clone(); //提取第一帧为背景帧60 imshow("video", frame);61 result = MoveDetect(background, frame);62 imshow("result", result);63 if(waitKey(50)==27)64 break;65 }66 }67 cap.release(); 68 }

和上一篇文章代码的不同点在30-38行,天台行人视频适合用背景减法处理,自行车视频适合帧差法处理

二、滤波方法去除噪声

 上篇文章中使用腐蚀膨胀消除噪声,这次使用滤波方法去除噪声

中值滤波

  //二值化后使用中值滤波+膨胀   Mat element = getStructuringElement(MORPH_RECT, Size(11, 11));    medianBlur(diff, diff, 5);//中值滤波    imshow("medianBlur", diff);    dilate(diff, diff, element);    imshow("dilate", diff);

均值滤波

#include "opencv2/opencv.hpp"#include
using namespace std;using namespace cv;//int to string helper functionstring intToString(int number){ stringstream ss; ss << number; return ss.str();}Mat MoveDetect(Mat background, Mat img){ Mat result = img.clone(); Mat gray1, gray2; cvtColor(background, gray1, CV_BGR2GRAY); cvtColor(img, gray2, CV_BGR2GRAY); Mat diff; absdiff(gray1, gray2, diff); threshold(diff, diff, 20, 255, CV_THRESH_BINARY); imshow("threshold", diff); blur(diff, diff, Size(10, 10));//均值滤波 imshow("blur", diff); vector
> contours; vector
hierarcy; findContours(diff, contours, hierarcy, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE); //查找轮廓 vector
boundRect(contours.size()); //定义外接矩形集合 //drawContours(img2, contours, -1, Scalar(0, 0, 255), 1, 8); //绘制轮廓 int x0=0, y0=0, w0=0, h0=0; for(int i=0; i
>frame; if(frame.empty()) break; else{ count++; if(count==1) background = frame.clone(); //提取第一帧为背景帧 imshow("video", frame); result = MoveDetect(background, frame); imshow("result", result); if(waitKey(50)==27) break; } } cap.release(); }

三、轮廓筛选去除噪声(效果挺好的)

//其余代码相同    int x0=0, y0=0, w0=0, h0=0;    for(int i=0; i
30 && h0>30) rectangle(result, Point(x0, y0), Point(x0+w0, y0+h0), Scalar(0, 255, 0), 2, 8); //绘制第i个外接矩形 }

四、运动轨迹绘制

#include "opencv2/opencv.hpp"#include
using namespace std;using namespace cv;Point center;Point fre_center;//存储前一帧中心坐标int num=0;vector
points;Mat MoveDetect(Mat background, Mat img){ Mat result = img.clone(); Mat gray1, gray2; cvtColor(background, gray1, CV_BGR2GRAY); cvtColor(img, gray2, CV_BGR2GRAY); Mat diff; absdiff(gray1, gray2, diff); imshow("absdiss", diff); threshold(diff, diff, 45, 255, CV_THRESH_BINARY); imshow("threshold", diff); Mat element = getStructuringElement(MORPH_RECT, Size(1, 1)); Mat element2 = getStructuringElement(MORPH_RECT, Size(9, 9)); erode(diff, diff, element); imshow("erode", diff); dilate(diff, diff, element2); imshow("dilate", diff); vector
> contours; vector
hierarcy; findContours(diff, contours, hierarcy, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE); //查找轮廓 vector
boundRect(contours.size()); //定义外接矩形集合 //drawContours(img2, contours, -1, Scalar(0, 0, 255), 1, 8); //绘制轮廓 vector
box(contours.size()); int x0=0, y0=0, w0=0, h0=0; for(int i=0; i
30 && h0>30)//筛选长宽大于30的轮廓 { num++; //rectangle(result, Point(x0, y0), Point(x0+w0, y0+h0), Scalar(0, 255, 0), 2, 8); //绘制第i个外接矩形 box[i] = fitEllipse(Mat(contours[i])); ellipse(result, box[i], Scalar(255, 0, 0), 2, 8); //椭圆轮廓 circle(result, box[i].center, 3, Scalar(0, 0, 255), -1, 8); //画中心 center = box[i].center;//当前帧的中心坐标 points.push_back(center);//中心塞进points向量集 if(num !=1) { //line(result, fre_center, center, Scalar(255, 0, 0), 2, 8); for(int j=0; j
>frame; if(!frame.empty()) { count++; if(count==1) background = frame.clone(); //提取第一帧为背景帧 imshow("video", frame); result = MoveDetect(background, frame); imshow("result", result); if(waitKey(30)==27) break; } else break; } cap.release(); }

五、车辆数量检测

1.帧差法检测运动目标

2.预处理:a.转灰度图,绝对值做差  b.二值化,腐蚀,中值滤波,膨胀  c.查找轮廓,筛选轮廓,绘制外接矩形,计数,输出

1 #include "opencv2/opencv.hpp" 2 #include
3 using namespace std; 4 using namespace cv; 5 6 int CarNum = 0; 7 //int to string helper function 8 string intToString(int number) 9 {10 //this function has a number input and string output11 stringstream ss;12 ss << number;13 return ss.str();14 }15 16 Mat MoveDetect(Mat frame1, Mat frame2) {17 Mat result = frame2.clone();18 Mat gray1, gray2;19 cvtColor(frame1, gray1, CV_BGR2GRAY);20 cvtColor(frame2, gray2, CV_BGR2GRAY);21 22 Mat diff;23 absdiff(gray1, gray2, diff);24 //imshow("absdiss", diff);25 threshold(diff, diff, 25, 255, CV_THRESH_BINARY);26 imshow("threshold", diff);27 28 Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));29 Mat element2 = getStructuringElement(MORPH_RECT, Size(19, 19));30 erode(diff, diff, element);31 //imshow("erode", dst);32 medianBlur(diff, diff, 3);33 imshow("medianBlur", diff);34 dilate(diff, diff, element2);35 imshow("dilate", diff);36 37 vector
> contours;38 vector
hierarcy;39 findContours(diff, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));//查找轮廓40 vector
>contours_poly(contours.size());41 vector
boundRect(contours.size()); //定义外接矩形集合42 //drawContours(img2, contours, -1, Scalar(0, 0, 255), 1, 8); //绘制轮廓43 int x0 = 0, y0 = 0, w0 = 0, h0 = 0;44 for (int i = 0; i
55 && boundRect[i].width<180 && boundRect[i].height>55 && boundRect[i].height<180) { //轮廓筛选49 x0 = boundRect[i].x;50 y0 = boundRect[i].y;51 w0 = boundRect[i].width;52 h0 = boundRect[i].height;53 54 rectangle(result, Point(x0, y0), Point(x0 + w0, y0 + h0), Scalar(0, 255, 0), 2, 8, 0);55 if ((y0 + h0 / 2 + 1) >= 138 && (y0 + h0 / 2 - 1) <= 142) { //经过这条线(区间),车辆数量+156 CarNum++;57 }58 }59 line(result, Point(0, 140), Point(568, 140), Scalar(0, 0, 255), 1, 8);//画红线60 Point org(0, 35);61 putText(result, "CarNum=" + intToString(CarNum), org, CV_FONT_HERSHEY_SIMPLEX, 0.8f, Scalar(0, 255, 0), 2);62 }63 return result;64 }65 66 void main()67 {68 VideoCapture cap("E://2.avi");69 if (!cap.isOpened()) //检查打开是否成功70 return;71 Mat frame;72 Mat tmp;73 Mat result;74 int count = 0;75 while (1)76 {77 cap >> frame;78 if(frame.empty())//检查视频是否结束79 break;80 else{81 count++;82 if (count == 1) 83 result = MoveDetect(frame, frame);84 else result = MoveDetect(tmp, frame);85 imshow("video", frame);86 imshow("result", result);87 tmp = frame.clone();88 if (waitKey(20) == 27) 89 break;90 }91 }92 cap.release();93 }

 

转载于:https://www.cnblogs.com/little-monkey/p/7637130.html

你可能感兴趣的文章
yield语句
查看>>
查看linux系统中占用cpu最高的语句
查看>>
[洛谷P1738]洛谷的文件夹
查看>>
ubuntu server设置时区和更新时间
查看>>
【京东咚咚架构演进】-- 好文收藏
查看>>
【HTML】网页中如何让DIV在网页滚动到特定位置时出现
查看>>
文件序列化
查看>>
jQuery之end()和pushStack()
查看>>
Bootstrap--响应式导航条布局
查看>>
Learning Python 009 dict(字典)和 set
查看>>
JavaScript中随着鼠标拖拽而移动的块
查看>>
HDU 1021 一道水题
查看>>
The operation couldn’t be completed. (LaunchServicesError error 0.)
查看>>
php每天一题:strlen()与mb_strlen()的作用分别是什么
查看>>
工作中收集JSCRIPT代码之(下拉框篇)
查看>>
《转载》POI导出excel日期格式
查看>>
code异常处理
查看>>
git - 搭建最简单的git server
查看>>
会话控制
查看>>
推荐一款UI设计软件Balsamiq Mockups
查看>>