在opencv的初等应用上,对运动物体的识别主要有帧差或背景差两种方式。

帧差法主要的原理是当前帧与前一帧作差取绝对值;

背景差主要的原理是当前帧与背景帧作差取绝对值

在识别运动车辆上主要需要以下9个步骤:

(1)读取帧(VideoCapture,Mat)

(2)ROI选定(Rect)

(3)平滑处理(GaussianBlur)

(4)灰度处理(cvtColor,CV_RGB2GRAY)

(5)帧差或背景差(absdiff)

(6)二值化(threshold)

(7)膨胀(dilate)

(8)腐蚀(erode)

(9)绘制运动车辆(findContours,rectangle)

(1)读取帧(外部视频读取:Videocapture;帧读取:Mat)

这个属于比较基础的内容这里不做解释,直接附上源码:

 /******************************************************
函数名称: MyClass
函数功能: 初始化
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
MyClass::MyClass()
{
//capture.open("F:/code/vsc++/Car_Find/Car_Find/交大七公里交通监控.avi");
capture.open("交大七公里交通监控.avi");
//capture = 0;
if (!capture.isOpened())//判断是否打开视频文件
{
exit();
}
FPS = capture.get(CV_CAP_PROP_FPS);
}
/******************************************************
函数名称: ~MyClass
函数功能: 释放空间
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
MyClass::~MyClass()
{
capture.release();
}
/******************************************************
函数名称: play
函数功能: 播放法
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
void MyClass::play(){
Mat frame;
namedWindow("播放界面按Esc退出", );
cvResizeWindow("播放界面按Esc退出", , );
while (true)
{
capture >> frame;
if (frame.empty())break;
imshow("播放界面按Esc退出", frame);
if (waitKey(1000.0 / FPS) == )//按原FPS显示
{
cout << "ESC退出!" << endl;
break;
}
}
}

处理结果:

(2)ROI选定(Rect)

这里使用Rect进行划ROI(感兴趣区域),画出一个矩阵的ROI。在这里最好的ROI是梯形(减少除了道路外的不必要的干扰)

这里提下做法:做一个灰度的mask(遮罩层),然后调整mask的形状大小。ps:感兴趣的可以做下。

(3)平滑处理(处理方法:GaussianBlur)

这里采用高斯平滑处理,在拍摄视频的时候会受到电流的干扰,但这个干扰时均匀存在的,所以采用高斯平滑处理可以去除电流的干扰。

方法很简单,源码如下:

 /******************************************************
函数名称: getSmooth
函数功能: 平滑处理
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
Mat MyClass::getSmooth(Mat frame)
{
Mat img;
GaussianBlur(frame, img, Size(, ),,);
return img;
}

处理结果:

(4)灰度处理(处理方法:cvtColor;核:CV_RGB2GRAY)

RGB的图对我们的识别会造成一定的干扰或者说增加处理的难度,这里将原帧转换为灰度图像;

在平滑处理 后,直接调用opencv的cvtColor方法:

 /******************************************************
函数名称: getGray
函数功能: 灰度处理
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
Mat MyClass::getGray(Mat frame)
{
Mat img;
cvtColor(frame, img, CV_RGB2GRAY);
return img;
}

处理结果:

(5)帧差或背景差(处理方法:absdiff)

不管是帧差和背景差都是需要获取当前帧跟对比帧,其中对比帧的获取和帧的作差是处理的关键。

在获取到处理好的灰度图在进行帧差处理。

以下为对比帧的获取 的源码:

 /******************************************************
函数名称: play
函数功能: 播放帧差法
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
void MyClass::play(){
Mat frame,preframe,curframe,result;
namedWindow("播放界面按Esc退出", );
//cvResizeWindow("播放界面按Esc退出", 600, 500);
while (true)
{
capture >> frame;
if (frame.empty())break;
if (preframe.empty())preframe = frame.clone();//首帧处理
curframe = frame.clone();
imshow("播放界面按Esc退出", frame);
if (waitKey(1000.0 / FPS) == )//按原FPS显示
{
cout << "ESC退出!" << endl;
break;
}
preframe = frame.clone();//记录当前帧为下一帧的前帧
}
}

以下为帧差处理的源码:

/******************************************************
函数名称: getDiff
函数功能: 帧差化处理
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
Mat MyClass::getDiff(Mat preframe,Mat frame)
{
Mat img;
absdiff(preframe, frame, img);
return img;
}

处理结果:

这里一个车的灰度轮廓已经可以识别出来了,但是我们的目的是将车辆的轮廓识别处理,为了更加精准,去除不必要的干扰,需要下面的处理。

(6)二值化(处理方法:threshold,阈值类型:CV_THRESH_BINARY)

Threshold函数详解,其中CV_THRESH_BINARY:当前点值大于阈值时,取Maxval,也就是第四个参数,下面再不说明,否则设置为0

由于这些车辆原画偏暗,这里设定阈值为30,处理当前点值大于阈值时,取白色255。

源码如下:

 /******************************************************
函数名称: getEz
函数功能: 二值化处理
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
Mat MyClass::getEz(Mat frame)
{
Mat img;
threshold(frame, img,, , CV_THRESH_BINARY);
return img;
}

处理结果:

车的黑白轮廓已经显示出来了,不过这里还不是一块整体,所以需要进行膨胀处理。

ps:有些博文的处理方式是先腐蚀处理后膨胀处理,这个在一定程度上会消除干扰点。但是这里考虑到车辆中有摩托车,如果先腐蚀处理的话会将摩托车给消除掉,造成识别精度不高。

(7)膨胀(处理方法:dilate)

膨胀的目的在于将一辆车拼合成一块完整的个体,以达到标识的目的

opencv提供了dilate的方法进行处理,源码如下:

 /******************************************************
函数名称: getPz
函数功能: 膨胀处理
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
Mat MyClass::getPz(Mat frame)
{
Mat img;
Mat element=getStructuringElement(MORPH_RECT, Size(, ));
dilate(frame, img, element);
return img;
}

处理结果:

这时候已经合成一块了,但是如果旁边的车靠的太近的话,会导致多辆车黏合成一块,所以下面做腐蚀处理。

(8)腐蚀(处理方法:erode)

腐蚀的目的在于将因为膨胀而导致的黏合,还有非关键点和区域的清除,以达到区分标识的目的。

opencv提供了erode的方法进行处理,源码如下:

 /******************************************************
函数名称: getFs
函数功能: 腐蚀处理
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
Mat MyClass::getFs(Mat frame)
{
Mat img;
Mat element = getStructuringElement(MORPH_RECT, Size(, ));
erode(frame, img, element);
return img;
}

处理结果:

ps:这里截的图不是很好,看不出效果分离的效果。感兴趣的可以下载下源码去调试。

(9)绘制运动车辆(处理方法:findContours,rectangle)

findContours函数参数详解

这里需要将车辆的外围轮廓描绘出来即可,所以findContours采用

mode取值“CV_RETR_EXTERNAL”,method取值“CV_CHAIN_APPROX_NONE”,即只检测最外层轮廓,并且保存轮廓上所有点;

rectangle的使用并不难,但是这里要注意的是:

a.处理的图像是原图像的ROI;

b.findContours输出的是处理过图像的坐标位置

所以在使用rectangle的时候,画区域的时候要加上原来ROI的起始位置的坐标,改成原来图像的坐标位置。

源码如下:

 /******************************************************
函数名称: Deal
函数功能: ROI区域处理
传入参数:
返 回 值:
建立时间: 2018-05-17
修改时间:
建 立 人:
修 改 人:
其它说明:
******************************************************/
Mat MyClass::Deal(Mat preframe, Mat frame)
{
Mat result = frame.clone();
Mat curimageROI = preframe(Rect(preframe.cols / , preframe.rows / , preframe.cols / 1.5, preframe.rows / 1.5));
Mat preimageROI = frame(Rect(frame.cols / , frame.rows / , frame.cols / 1.5, frame.rows / 1.5)); Mat sm_pre, sm_cur;
sm_pre = getSmooth(preimageROI);
sm_cur = getSmooth(curimageROI);
imshow("平滑处理", sm_cur); Mat gray_pre, gray_cur;
gray_pre = getGray(sm_pre);
gray_cur = getGray(sm_cur);
imshow("灰度处理",gray_cur); Mat diff;
diff = getDiff(gray_pre, gray_cur);
imshow("帧差处理",diff); Mat ez;
ez = getEz(diff);
imshow("二值化处理", ez); Mat pz;
pz = getPz(ez);
imshow("膨胀处理", pz); Mat fs;
fs = getFs(pz);
imshow("腐蚀处理", fs); vector<vector<Point> > contours;
findContours(fs, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
vector<Rect> boundRect(contours.size());
for (int i = ; i < contours.size(); i++)
{
boundRect[i] = boundingRect(contours[i]);
rectangle(result, Rect(boundRect[i].x + frame.cols/, boundRect[i].y + frame.rows/, boundRect[i].width, boundRect[i].height), Scalar(, , ), );//在result上绘制正外接矩形
}
return result;
}

处理结果:

这里效果不是非常好可以勉强识别出车辆轮廓。但作为初级应用是足够的。

如需要源码请转移至码云:https://gitee.com/cjqbaba/MediaTest/tree/Car_Find进行源码克隆下载

如有问题请留言评论。转载请注明出处,谢谢。

基于opencv3.0下的运动车辆识别的更多相关文章

  1. 基于opencv3.0下的人脸检测和检测部分的高斯模糊处理

    如题 这里将任务分解为三大部分: 1.录播放视频 2.人脸检测 3.部分高斯模糊 其中重点放在人脸检测和部分高斯模糊上 1.录播放视频(以opencv中的VideoCapture类进行实现) 首先罗列 ...

  2. 基于opencv3.0和下的条形码与二维码识别

    其中对条码与二维码的识别分为以下4个步骤 1. 利用opencv和Zbar(或者Zxing)对标准的条形码图片(即没有多余背景干扰,且图片没有倾斜)进行解码,将解码信息显示出来,并与原始信息对比. 2 ...

  3. 【OpenCV】opencv3.0中的SVM训练 mnist 手写字体识别

    前言: SVM(支持向量机)一种训练分类器的学习方法 mnist 是一个手写字体图像数据库,训练样本有60000个,测试样本有10000个 LibSVM 一个常用的SVM框架 OpenCV3.0 中的 ...

  4. ubuntu14.04下安装cudnn5.1.3,opencv3.0,编译caffe及配置matlab和python接口过程记录

    已有条件: ubuntu14.04+cuda7.5+anaconda2(即python2.7)+matlabR2014a 上述已经装好了,开始搭建caffe环境. 1. 装cudnn5.1.3,参照: ...

  5. ubuntu14.04下配置使用openCV3.0

    [操  作  系  统] Ubuntu 14.04 LTS [OpenCV版本]  3.0.0-beta [Eclipse 版 本] 3.8.1 需要知识: Linux系统shell命令基础 编译原理 ...

  6. windows下配置caffe(环境:win7+vs2013+opencv3.0)

    说明:大部分转载于initialneil的大作Caffe + vs2013 + OpenCV in Windows Tutorial (I) – Setup 准备工作: 1.下载CUDA7.5: ht ...

  7. 在CUDA8.0下编译安装OpenCV3.1.0来实现GPU加速(Compiling OpenCV3.1.0 with CUDA8.0 support)

    在CUDA8.0下编译安装OpenCV3.1.0 一.本人电脑配置:ubuntu 14.04, NVIDIA GTX1060. 二.编译OpenCV3.1.0前,读者需要成功安装CUDA8.0(网上有 ...

  8. 在win10下给vs2013配置opencv3.0

    opencv这玩意是真难搞呀. 先吐槽下..... 下面进入正文. 1准备工具: opencv3.0+vs2013 这里面不提供链接下载,自行谷歌百度. 2配置环境: a.打开下载好的opencv(解 ...

  9. 在已配置成功的opencv3.2.0下配置opencv_contrib模块

    简介: 之前在Ubuntu下配置OpenCV时,因为对opencv3..0不是特别了解,没有把opencv_contrib进行安装,这里提醒大家尽量要一次性安装完毕,减少不必要的麻烦. .0文件夹 ( ...

随机推荐

  1. 在FFMPEG中使用libRTMP的经验

    FFMPEG在编译的时候可以选择支持RTMP的类库libRTMP.这样ffmpeg就可以支持rtmp://, rtmpt://, rtmpe://, rtmpte://,以及 rtmps://协议了. ...

  2. OpenCV 实现分水岭算法

    种子点的标记没有太搞懂,这个算法的速度还是很快的 // watershed_test20140801.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h&q ...

  3. 【58】Spring总结之注解(2)

    启用注解配置: 1.context:annotation-config 该配置表示启用注解. 2.context:component-scan base-package="." 该 ...

  4. C语言之归并排序

    即将两个都升序(或降序)排列的数据序列合并成一个仍按原序排列的序列. 上代码: #include <stdio.h> #include <stdlib.h> #define m ...

  5. Linux set命令参数及用法详解

    linux  set 命令 功能说明:设置shell. 语 法:set [+-abCdefhHklmnpPtuvx] 补充说明:用set 命令可以设置各种shell选项或者列 出shell变量.单个选 ...

  6. 【ROM修改教程】添加高级电源重启菜单(安卓4.0.4官方ROM)

    准备工作: 电脑上安装好JDK.下载smali和baksmali.下载apktools.要修改的ROM.adb工具(可选) 注:由于本教程面向的对象为有一定ROM修改基础的兄弟,所以对于如何使用电脑, ...

  7. PS 滤镜算法原理——高反差保留 (High Pass)

    这个特效简单来说,就是一个高通滤波器, 对图像做高斯滤波,用原图减去高斯滤波后的图,再将差值加上128. clc; clear all; close all; Image=imread('4.jpg' ...

  8. 微信android混淆打包减少安装包大小

    首先,感谢微信android团队的分享 微信中的资源混淆工具主要为了混淆资源ID长度(例如将res/drawable/welcome.png混淆为r/s/a.png),同时利用7z深度压缩,大大减少了 ...

  9. Runtime - ③ - 分类Category探究

    写博客只是为了让自己学的更深刻,参考:https://tech.meituan.com/DiveIntoCategory.html 分类(Category)是个啥玩意儿这里就不多介绍了,这里主要是研究 ...

  10. 添加极光推送以及在ios中的问题

    项目为 ionic1 + angular1 1.添加极光推送插件 用cordova进行添加 cordova plugin add jpush-phonegap-plugin --variable AP ...