【OpenCV】 车辆识别 运动目标检测
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
一车辆识别 运动目标检测
二车辆识别实现 超详细步骤解析
步骤一灰度化处理
灰度处理目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
效果展示【避免内存浪费 帧差法对前后帧图像灰度化处理】 cvtColor
//1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
cvtColor(frontFrame,frontGray,CV_RGB2GRAY);//前一帧灰度化处理
cvtColor(afterFrame,afterGray,CV_RGB2GRAY);//后一帧灰度化处理
//imshow("frontGray",frontGray);//测试
//imshow("afterGray",afterGray);//测试
步骤二帧差处理
帧差处理目的 找到帧与帧之间的差异找出正在运动的物体
效果展示【运动目标的检测运动事物显示灰度静止事物显示黑度】 absdiff
//2 帧差处理 目的 找到帧与帧之间的差异(正在运动的物体)
Mat diff;
Mat frontGray,afterGray;
absdiff(frontGray,afterGray,diff);//前后帧对比存于diff中
imshow("diff",diff);//测试
步骤三二值化处理
二值化处理 目的 将灰度图继续识别转换为黑白分明的图像 threshold
效果展示【步骤二中运动事物显示灰度静止事物显示黑度在这里进行二值化处理能够黑白分明便于计算机识别运动目标如下右图二值化处理后黑白分明】【缺点存在白色噪点如下右图除了车辆外后面的背景也显示白度这就是白色噪点需要去除】
//3 二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
threshold(diff,diff,25,255,CV_THRESH_BINARY);
imshow("threshold",diff);//测试
步骤四图像降噪
4-1 腐蚀处理 目的 去除白色噪点
效果展示【步骤三中存在的白色噪点能够去除但是在去除白色噪点的同时也影响了车辆的白度显示如下右图可以看出车辆白度显示有所降低因此还是需要改进】erode
//4 图像降噪
//4-1 腐蚀处理 目的 去除白色噪点
Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));//小于3*3方块的白色噪点都会被腐蚀
erode(diff,diff,element);
imshow("erode",diff);//测试
4-2 膨胀处理 目的 把白色区域变大
效果展示【如下右图膨胀处理将车辆形状大致显示便于框选车辆识别操作】dilate
//4-2 膨胀 目的 把白色区域变大
Mat element2=cv::getStructuringElement(MORPH_RECT,Size(20,20));
dilate(diff,diff,element2);
imshow("dilate",diff);//测试
步骤五提取关键点 框选运动目标检测
效果展示车辆识别 运行目标检测 框选识别行进的车辆
//5 提取关键点
//5-1 查找特征点
vector<vector<Point>>contours;
findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
//5-2 提取关键点
vector<vector<Point>>contours_poly(contours.size());
vector<Rect>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 <iostream>
#include <opencv2/opencv.hpp>
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<vector<Point>>contours;
findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
//5-2 提取关键点
vector<vector<Point>>contours_poly(contours.size());
vector<Rect>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;
}
对于夜晚的行进的车辆也能够正常识别
不过本次帧差法的车辆识别存在弊端只要是运动的物体都会识别比如博主打开摄像头动一动手指头也会被框选识别因此是有一定弊端的
但是帧差法的运动目标检测在夜晚监控中是非常广泛地应用到因为有任何的风吹草动都会被框选识别可以用于安防管理