EN
/news/show.php/video/64261995.html

【OpenCV】“帧差法”实现移动物体的检测(车辆识别)

2025-06-24 11:48:22 来源: 新华社
字号:默认 超大 | 打印 |

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:xhs1999xhs (备注Java)
img

正文

目录

一、帧差法

1、概念

2、为什么帧差法可以检测运动的物体?

二、使用OpenCV配合帧差法实现车辆识别

1、加载视频

2、灰度处理+帧差计算

3、二值化

4、腐蚀

5、膨胀

6、框选出车辆

三、全部代码+实现效果

1、代码

2、车辆检测效果

四、帧差法存在不足之处


一、帧差法

1、概念

帧差法是一种通过对视频图像序列中 相邻两帧作差分运算来获得运动目标轮廓的方法,它可以很好地适用于存在多个运动目标和摄像机移动的情况。

当监控场景中出现异常物体运动时,帧与帧之间会出现较为明显的差别,两帧相减,得到两帧图像 亮度差的绝对值,判断它是否大于 阈值来分析视频或图像序列的运动特性,确定图像序列中有无物体运动。

2、为什么帧差法可以检测运动的物体?

😎还记得小时候的葫芦娃动画吗?每个人物其实都是一张剪纸,也被叫做“剪纸动画”,剪一张就是一帧,假设葫芦娃动画为每秒25帧,1秒内连续播放25张不同的剪纸。

😎因为每一帧之间是有差异的,所以我们可以看到剪纸起来了。

  • 😋博主演示一遍剪纸动画,让大家更直观的感受

博主有以下同一条鲨鱼的不同形态的png图片,使用图片查看来切换显示每一张图片

👀可以看到鲨鱼动起来了!!!

😎因此可以通过判断 前后两帧是否相同,来判断是否有运动的物体,即通过帧差法来检测运动的物体。

😁所以下面跟着博主来学习使用OpenCV通过帧差法来进行移动车辆的识别。当然不止可以识别车辆,其他移动的物体也可以识别。

二、使用OpenCV配合帧差法实现车辆识别

  • 开发工具

🔎Qt 5.8.0  +  OpenCV

1、加载视频

  • 通过VideoCapture来加载本地视频,循环读取每一帧并进行显示
int main(int argc, char *argv[]){     Mat frame;    VideoCapture cap("D:/QT-Project/image/carMove.mp4");    while(cap.read(frame))    {         //读取一帧显示一帧        imshow("frame", frame);        //延时        waitKey(25);    }    return 0;}

2、灰度处理+帧差计算

  • 为了提高计算机的运算速度,图像处理前一般将图像转成灰度图

因为彩色图片是3通道(RGB)24位深度的图像,而灰度图是单通道8位深度的图像,因此处理灰度图比彩色图效率快多了。

  • frontMat为前一帧,afterMat为后一帧
//灰度处理cvtColor(frontMat, frontGray, CV_BGR2GRAY);cvtColor(afterMat, afterGray, CV_BGR2GRAY);//帧差处理 找到帧与帧之间运动的物体差异absdiff(frontGray, afterGray, diffGray);
  • 效果:原图(左)、处理后(右)

通过下图可以发现检测是检测出来了,但是画面非常的暗淡(不清晰),因此需要通过二值化来让图像更清晰点。

3、二值化

  • 通过threshold函数将图像二值化

参数一为原图,参数二为处理后的图,直接将处理后的图覆盖掉原图即可

//二值化:黑白分明 会产生大量白色噪点threshold(diffGray, diffGray, 25, 255, CV_THRESH_BINARY);
  • 下面是二值化处理过后的效果

可以发现图像确实是变“清晰”了,因为二值化后的图像只有黑白两种颜色。并且我们还可以发现白色噪点非常多,因为摄像机抖动,风吹树叶等原因,因此还需要通过腐蚀来去除掉这些白色噪点。

4、腐蚀

  • 概念

腐蚀是针对图片的二值化数据进行操作的,主要是针对高亮部分。使用算法,将图像的边缘腐蚀掉。作用就是将目标的边缘的“毛刺”踢除掉。

如下图所示:

  • 通过erode函数将图像进行腐蚀
//腐蚀处理:去除白色噪点 噪点不能完全去除,反而主要物体会被腐蚀的图案都变得不明显Mat element = cv::getStructuringElement(MORPH_RECT, Size(3, 3));erode(diffGray, diffGray, element);
  • 下面是腐蚀之后的效果

😧白色噪点确实是被去除了,但是我们的车辆也被腐蚀的不成车样(内部坑坑洼洼的),所以还需要通过膨胀将车辆进行进一步处理。

5、膨胀

  • 概念

膨胀是针对图片的二值化数据进行操作的,主要是针对高亮部分。使用算法,将图像的边缘扩大些。作用就是将目标的边缘或者是内部的坑填掉。

如下图所示:

  • 通过dilate函数将图像进行膨胀
//膨胀处理:将白色区域变“胖”Mat element2 = cv::getStructuringElement(MORPH_RECT, Size(20, 20));dilate(diffGray, diffGray, element2);
  • 下面是膨胀之后的效果

我们的车辆变成一个个大方块了,做到这一步差不多就可以来标记运动的车辆了,只要画矩形将白色大方块框起来即可。

6、框选出车辆

  • 下面是用白色的框框,框选出来的效果

框选的原理就是找到白色方块最左边的点与最右边的点,得到之间的大小差距(矩形宽),找到白色方块最上边的点与最下边的点,得到之间的大小差距(矩形高)。

通过宽高即可画出一个把白色方块包含在内的矩形,矩形左上角坐标通过白色方块最上方的值和最左方的值来确定。

  • 我们只要将白色方框改个显眼的颜色,并在原视频的对应位置画出这个框框即可。下面附全部代码。

三、全部代码+实现效果

1、代码

#include <iostream>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;//帧差法检测车辆Mat MoveCheck(Mat &frontMat, Mat &afterMat){     Mat frontGray ,afterGray, diffGray;    Mat resframe = afterMat.clone();    //灰度处理    cvtColor(frontMat, frontGray, CV_BGR2GRAY);    cvtColor(afterMat, afterGray, CV_BGR2GRAY);    //imshow("GRAY", frontGray);    //帧差处理 找到帧与帧之间运动的物体差异    //缺点:会把其他运动物体也算进来    absdiff(frontGray, afterGray, diffGray);    //imshow("absdiff", diffGray);    //二值化:黑白分明 会产生大量白色噪点    threshold(diffGray, diffGray, 25, 255, CV_THRESH_BINARY);    //imshow("diff", diffGray);    //腐蚀处理:去除白色噪点 噪点不能完全去除,反而主要物体会被腐蚀的图案都变得不明显    Mat element = cv::getStructuringElement(MORPH_RECT, Size(3, 3));    erode(diffGray, diffGray, element);    //imshow("erode", diffGray);    //膨胀处理:将白色区域变“胖”    Mat element2 = cv::getStructuringElement(MORPH_RECT, Size(20, 20));    dilate(diffGray, diffGray, element2);    //imshow("dilate", diffGray);    //动态物体标记    vector<vector<Point>> contours; //保存关键点    findContours(diffGray, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));    //提取关键点    vector<vector<Point>> contours_poly(contours.size());    vector<Rect> boundRect(contours.size());    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, 255, 0), 4);    }    return resframe;}int main(int argc, char *argv[]){     Mat frame;    Mat tempframe;    Mat res;    int count = 0;    VideoCapture cap("D:/QT-Project/image/carMove.mp4");    while(cap.read(frame))    {         count++;        if(count == 1)        {             res = MoveCheck(frame, frame);        }        else        {             res = MoveCheck(tempframe, frame);        }        tempframe = frame.clone();        imshow("frame", frame);//原视频帧        imshow("res", res);//框选后的视频帧        waitKey(25);    }    return 0;}

2、车辆检测效果

四、帧差法存在不足之处

  • 相机抖动+起风了

帧差法虽然能够检测出运动的车辆,但是不仅包括车辆,任何运动的物体都会检测出来,就像上图所示,一旦相机抖动或者突然起大风,运动的物体就多了起来(两帧差异的地方很多),因此就会出现上面那种情况。

😘The end ……🔚

原创不易,转载请标明出处。

对您有帮助的话可以一键三连,会持续更新的(嘻嘻)。

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

最新整理面试题
在这里插入图片描述

上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题

最新整理电子书

在这里插入图片描述

最新整理大厂面试文档

在这里插入图片描述

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:xhs1999xhs (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
面经。希望可以帮助到大家。

最新整理面试题
[外链图片转存中…(img-U8FF0FsA-1713683761385)]

上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题

最新整理电子书

[外链图片转存中…(img-instT1Gn-1713683761386)]

最新整理大厂面试文档

[外链图片转存中…(img-R9JXRvJ7-1713683761386)]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:xhs1999xhs (备注Java)
[外链图片转存中…(img-PWZW8lqA-1713683761386)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

【我要纠错】责任编辑:新华社