• 【OpenCV】 车辆识别 运动目标检测


    目录

    一:车辆识别成果展示

    二:车辆识别超详细步骤解析

    步骤一:灰度化处理

    步骤二:帧差处理

    步骤三:二值化处理

    步骤四:图像降噪

    4-1 腐蚀处理 目的 去除白色噪点

    4-2 膨胀处理 目的 把白色区域变大

    步骤五:提取关键点 框选运动目标检测

    三:车辆识别完整代码


    一:车辆识别成果展示

    二:车辆识别超详细步骤解析

    步骤一:灰度化处理

    灰度处理目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小

    效果展示:【避免内存浪费 帧差法对前后帧图像灰度化处理】

    1. //1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
    2. cvtColor(frontFrame,frontGray,CV_RGB2GRAY);//前一帧灰度化处理
    3. cvtColor(afterFrame,afterGray,CV_RGB2GRAY);//后一帧灰度化处理
    4. //imshow("frontGray",frontGray);//测试
    5. //imshow("afterGray",afterGray);//测试

     步骤二:帧差处理

    帧差处理目的 找到帧与帧之间的差异(正在运动的物体)

    效果展示:【运动目标的检测:运动事物显示灰度,静止事物显示黑度】

    1. //2 帧差处理 目的 找到帧与帧之间的差异(正在运动的物体)
    2. Mat diff;
    3. Mat frontGray,afterGray;
    4. absdiff(frontGray,afterGray,diff);//前后帧对比存于diff中
    5. imshow("diff",diff);//测试

    步骤三:二值化处理

    二值化处理 目的 将灰度图继续识别转换为黑白分明的图像

    效果展示:【步骤二中运动事物显示灰度,静止事物显示黑度,在这里进行二值化处理,能够黑白分明,便于计算机识别运动目标,如下右图二值化处理后黑白分明】【缺点:存在白色噪点,如下右图除了车辆外后面的背景也显示白度,这就是白色噪点,需要去除】

    1. //3 二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
    2. threshold(diff,diff,25,255,CV_THRESH_BINARY);
    3. imshow("threshold",diff);//测试

    步骤四:图像降噪

    4-1 腐蚀处理 目的 去除白色噪点

    效果展示:【步骤三中存在的白色噪点能够去除,但是在去除白色噪点的同时,也影响了车辆的白度显示,如下右图可以看出,车辆白度显示有所降低,因此还是需要改进】

    1. //4 图像降噪
    2. //4-1 腐蚀处理 目的 去除白色噪点
    3. Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));//小于3*3方块的白色噪点都会被腐蚀
    4. erode(diff,diff,element);
    5. imshow("erode",diff);//测试

    4-2 膨胀处理 目的 把白色区域变大

    效果展示:【如下右图,将车辆形状大致显示,便于框选车辆识别操作】

    1. //4-2 膨胀 目的 把白色区域变大
    2. Mat element2=cv::getStructuringElement(MORPH_RECT,Size(20,20));
    3. dilate(diff,diff,element2);
    4. imshow("dilate",diff);//测试

    步骤五:提取关键点 框选运动目标检测

    效果展示:车辆识别成功

    1. //5 提取关键点
    2. //5-1 查找特征点
    3. vector>contours;
    4. findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
    5. //5-2 提取关键点
    6. vector>contours_poly(contours.size());
    7. vectorboundRect(contours.size());
    8. //5-3 确定下四个点来用于框选目标物体
    9. int x,y,w,h;
    10. int num=contours.size();
    11. for(int i = 0;i < num;i++)
    12. {
    13. approxPolyDP(Mat(contours[i]),contours_poly[i],3,true);
    14. //多边拟合
    15. boundRect[i]=boundingRect(Mat(contours_poly[i]));
    16. x=boundRect[i].x;
    17. y=boundRect[i].y;
    18. w=boundRect[i].width;
    19. h=boundRect[i].height;
    20. //绘制矩形
    21. rectangle(resFrame,Point(x,y),Point(x+w,y+h),Scalar(0,0,255),2);
    22. }

    三:车辆识别完整代码

    1. #include
    2. #include
    3. using namespace std;
    4. using namespace cv;
    5. Mat moveCheck(Mat &frontFrame,Mat &afterFrame)
    6. {
    7. Mat resFrame,diff;
    8. Mat frontGray,afterGray;
    9. //克隆当前帧画面 返回最终结果
    10. resFrame = afterFrame.clone();
    11. //1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
    12. cvtColor(frontFrame,frontGray,CV_RGB2GRAY);
    13. cvtColor(afterFrame,afterGray,CV_RGB2GRAY);
    14. //imshow("frontGray",frontGray);
    15. //imshow("afterGray",afterGray);
    16. //2 帧差处理 目的 找到帧与帧之间的差异(正在运动的物体)
    17. absdiff(frontGray,afterGray,diff);
    18. //imshow("diff",diff);
    19. //3 二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
    20. threshold(diff,diff,25,255,CV_THRESH_BINARY);
    21. //imshow("threshold",diff);
    22. //4 图像降噪
    23. //4-1 腐蚀处理 目的 去除白色噪点
    24. Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));//小于3*3方块的白色噪点都会被腐蚀
    25. erode(diff,diff,element);
    26. //imshow("erode",diff);
    27. //4-2 膨胀 目的 把白色区域变大
    28. Mat element2=cv::getStructuringElement(MORPH_RECT,Size(20,20));
    29. dilate(diff,diff,element2);
    30. //imshow("dilate",diff);
    31. //5 提取关键点
    32. //5-1 查找特征点
    33. vector>contours;
    34. findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
    35. //5-2 提取关键点
    36. vector>contours_poly(contours.size());
    37. vectorboundRect(contours.size());
    38. //5-3 确定下四个点来用于框选目标物体
    39. int x,y,w,h;
    40. int num=contours.size();
    41. for(int i = 0;i < num;i++)
    42. {
    43. approxPolyDP(Mat(contours[i]),contours_poly[i],3,true);
    44. //多边拟合
    45. boundRect[i]=boundingRect(Mat(contours_poly[i]));
    46. x=boundRect[i].x;
    47. y=boundRect[i].y;
    48. w=boundRect[i].width;
    49. h=boundRect[i].height;
    50. //绘制矩形
    51. rectangle(resFrame,Point(x,y),Point(x+w,y+h),Scalar(0,0,255),2);
    52. }
    53. return resFrame;
    54. }
    55. int main(int argc, char *argv[])
    56. {
    57. Mat frame;
    58. Mat temp;
    59. Mat res;
    60. int count = 0;
    61. VideoCapture cap("D:/00000000000003jieduanshipincailliao/carMove.mp4");//视频路径
    62. while (cap.read(frame))
    63. {
    64. count++;
    65. if(count == 1)
    66. {
    67. res = moveCheck(frame,frame);
    68. }
    69. else
    70. {
    71. res = moveCheck(temp,frame);
    72. }
    73. imshow("frame",frame);
    74. imshow("res",res);//最终车辆识别成果
    75. temp = frame.clone();
    76. waitKey(15);
    77. }
    78. return 0;
    79. }

    当然,夜晚的车辆也能够正常识别

    不过,本次的帧差法的车辆识别存在弊端,只要是运动的物体都会识别,比如,博主打开摄像头,动一动手指头,也会被框选识别,因此是有一定弊端的

    不过,这种帧差法的运动目标检测,在夜晚监控中是非常广泛地应用到,因为有任何的风吹草动,都会被框选识别。 

  • 相关阅读:
    主机安全加固
    Kotlin 协程之取消与异常处理探索之旅(下)
    国产数据库人大金仓V8
    IoT物联网速成课程
    React 基础学习
    算法与数据结构 - 栈详解
    gltf模型加载 与3d背景贴图
    x64 番外篇——知识铺垫
    MyBatis构建SQL
    服务端Skynet(三)——启动lua服务
  • 原文地址:https://blog.csdn.net/m0_56051805/article/details/126062172