识别车辆
1.原理简介
在我们录制的视频中,车辆是其中最明显的移动 物体,而背景的其他物体几乎是静止的(或者是微小的移动,可以被后续处理掉),因此我们可以直观地想到使用帧差法识别车辆。
帧差法是车辆识别中最简单的方法,一般选取2-3帧计算差值。对于两帧的帧差法,取当前帧与前一帧的差值,对应的像素点相减,判断灰度差的绝对值。随后经过高斯滤波、膨胀、腐蚀等处理,可以较好地得到汽车的轮廓,从而进行识别。对于三帧的帧差法,一般来讲我们将前两帧计算差值,再将当前帧与其前一帧进行差值,再把两个差值按像素点进行“与”操作,得到差值图片,后续再经过其他处理得到轮廓。三帧法的好处是可以有效地对运动物体进行检测,可以有效减少输出结果的“鬼影”,但是当物体移速较低时可能会丢失物体的轮廓。在本项目中,使用二帧差法,一方面是因为视频车流的速度不算太块,另一方面三帧差法和二帧差法原理基本一致,因此先从二帧差尝试。
2.代码实现(部分)
首先我们通过opencv的videocap.open打开目标视频,并利用videocap.get(CV_CAP_PROP_FPS)获取视频帧数。
我们将视频前一帧与后一帧获取并输入deal()函数进行处理,deal()函数将在下文进行分析,如果前一帧没有,则将当前帧复制作前一帧。Videocap为之前声明的变量。用videocap.open(“D:/test.mp4”);打开目标视频。
}
Mat frame, preframe, curframe, result;
namedWindow("Tap ESC to exit", 0);
while (true)
{
videocap >> frame;
if (frame.empty()) break;
if (preframe.empty()) preframe = frame.clone();
curframe = frame.clone();
result = deal(preframe, curframe);
}
Deal()为对获取的两帧进行帧差法处理,代码如下所示:其中get_Gsmooth()、get_grey、get_diff、binaryzation、expand、erosion均为定义的函数,负责各个处理环节,随后使用findContours函数对物体轮廓进行检测,最后再画框框把结果标记起来。
Mat result = frame.clone();
//Mat curimageROI = preframe(Rect(preframe.cols / 5, preframe.rows / 5, preframe.cols / 1.5, preframe.rows / 1.5));
//Mat preimageROI = frame(Rect(frame.cols / 5, frame.rows / 5, frame.cols / 1.5, frame.rows / 1.5));
Mat curimageROI = preframe;
Mat preimageROI = frame;
Mat sm_pre, sm_cur;
sm_pre = get_Gsm