目录
灰度处理目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
效果展示:【避免内存浪费 帧差法对前后帧图像灰度化处理】
- //1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
- cvtColor(frontFrame,frontGray,CV_RGB2GRAY);//前一帧灰度化处理
- cvtColor(afterFrame,afterGray,CV_RGB2GRAY);//后一帧灰度化处理
- //imshow("frontGray",frontGray);//测试
- //imshow("afterGray",afterGray);//测试
帧差处理目的 找到帧与帧之间的差异(正在运动的物体)
效果展示:【运动目标的检测:运动事物显示灰度,静止事物显示黑度】
- //2 帧差处理 目的 找到帧与帧之间的差异(正在运动的物体)
- Mat diff;
- Mat frontGray,afterGray;
- absdiff(frontGray,afterGray,diff);//前后帧对比存于diff中
- imshow("diff",diff);//测试
二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
效果展示:【步骤二中运动事物显示灰度,静止事物显示黑度,在这里进行二值化处理,能够黑白分明,便于计算机识别运动目标,如下右图二值化处理后黑白分明】【缺点:存在白色噪点,如下右图除了车辆外后面的背景也显示白度,这就是白色噪点,需要去除】
- //3 二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
- threshold(diff,diff,25,255,CV_THRESH_BINARY);
- imshow("threshold",diff);//测试
效果展示:【步骤三中存在的白色噪点能够去除,但是在去除白色噪点的同时,也影响了车辆的白度显示,如下右图可以看出,车辆白度显示有所降低,因此还是需要改进】
- //4 图像降噪
- //4-1 腐蚀处理 目的 去除白色噪点
- Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));//小于3*3方块的白色噪点都会被腐蚀
- erode(diff,diff,element);
- imshow("erode",diff);//测试
效果展示:【如下右图,将车辆形状大致显示,便于框选车辆识别操作】
- //4-2 膨胀 目的 把白色区域变大
- Mat element2=cv::getStructuringElement(MORPH_RECT,Size(20,20));
- dilate(diff,diff,element2);
- imshow("dilate",diff);//测试
效果展示:车辆识别成功
- //5 提取关键点
- //5-1 查找特征点
- vector
>contours; - findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
-
- //5-2 提取关键点
- vector
>contours_poly(contours.size()); - vector
boundRect(contours.size()); -
- //5-3 确定下四个点来用于框选目标物体
- int x,y,w,h;
- int num=contours.size();
- for(int i = 0;i < num;i++)
- {
- approxPolyDP(Mat(contours[i]),contours_poly[i],3,true);
- //多边拟合
- boundRect[i]=boundingRect(Mat(contours_poly[i]));
- x=boundRect[i].x;
- y=boundRect[i].y;
- w=boundRect[i].width;
- h=boundRect[i].height;
- //绘制矩形
- rectangle(resFrame,Point(x,y),Point(x+w,y+h),Scalar(0,0,255),2);
- }
- #include
- #include
-
- using namespace std;
- using namespace cv;
-
- Mat moveCheck(Mat &frontFrame,Mat &afterFrame)
- {
- Mat resFrame,diff;
- Mat frontGray,afterGray;
-
- //克隆当前帧画面 返回最终结果
- resFrame = afterFrame.clone();
-
- //1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
- cvtColor(frontFrame,frontGray,CV_RGB2GRAY);
- cvtColor(afterFrame,afterGray,CV_RGB2GRAY);
-
- //imshow("frontGray",frontGray);
- //imshow("afterGray",afterGray);
-
- //2 帧差处理 目的 找到帧与帧之间的差异(正在运动的物体)
- absdiff(frontGray,afterGray,diff);
- //imshow("diff",diff);
-
- //3 二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
- threshold(diff,diff,25,255,CV_THRESH_BINARY);
- //imshow("threshold",diff);
-
- //4 图像降噪
- //4-1 腐蚀处理 目的 去除白色噪点
- Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));//小于3*3方块的白色噪点都会被腐蚀
- erode(diff,diff,element);
- //imshow("erode",diff);
-
- //4-2 膨胀 目的 把白色区域变大
- Mat element2=cv::getStructuringElement(MORPH_RECT,Size(20,20));
- dilate(diff,diff,element2);
- //imshow("dilate",diff);
-
- //5 提取关键点
- //5-1 查找特征点
- vector
>contours; - findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
-
- //5-2 提取关键点
- vector
>contours_poly(contours.size()); - vector
boundRect(contours.size()); -
- //5-3 确定下四个点来用于框选目标物体
- int x,y,w,h;
- int num=contours.size();
- for(int i = 0;i < num;i++)
- {
- approxPolyDP(Mat(contours[i]),contours_poly[i],3,true);
- //多边拟合
- boundRect[i]=boundingRect(Mat(contours_poly[i]));
- x=boundRect[i].x;
- y=boundRect[i].y;
- w=boundRect[i].width;
- h=boundRect[i].height;
- //绘制矩形
- rectangle(resFrame,Point(x,y),Point(x+w,y+h),Scalar(0,0,255),2);
- }
-
- return resFrame;
- }
-
- int main(int argc, char *argv[])
- {
- Mat frame;
- Mat temp;
- Mat res;
- int count = 0;
-
- VideoCapture cap("D:/00000000000003jieduanshipincailliao/carMove.mp4");//视频路径
-
- while (cap.read(frame))
- {
- count++;
- if(count == 1)
- {
- res = moveCheck(frame,frame);
- }
- else
- {
- res = moveCheck(temp,frame);
- }
- imshow("frame",frame);
- imshow("res",res);//最终车辆识别成果
- temp = frame.clone();
- waitKey(15);
- }
- return 0;
- }
当然,夜晚的车辆也能够正常识别
不过,本次的帧差法的车辆识别存在弊端,只要是运动的物体都会识别,比如,博主打开摄像头,动一动手指头,也会被框选识别,因此是有一定弊端的
不过,这种帧差法的运动目标检测,在夜晚监控中是非常广泛地应用到,因为有任何的风吹草动,都会被框选识别。