《opencv实战》 之 车牌定位

目标:  提取车牌所在的区域

       PS:现在还没学习文字检测,以后再来补充~~

思路:

    1.利用形态学+梯度+轮廓检测,但是这个形态学要求比较高,得调节到适当的参数。

    2.利用HSV颜色分离+梯度+形态学+轮廓检测,这个方法的适应度比较高,行比较上面的方法较难理解。

本文使用第二种方法实现:

PS:不要问为什么用这种方法,没有为什么的方法,只有解决问题的方法,手动操作一下就懂了。

先上效果图:

梯度检测图(1-1)

S空间图(1-2)

S空间分离蓝色图(1-3)

(HSV图像分离+梯度)结合图(1-4)

轮廓检测处理图(1-5)

最终效果图(1-6)

上代码:

  1 #if 1
  2 #include <opencv2/opencv.hpp>
  3 #include <iostream>
  4 #include "math.h"
  5
  6 using namespace cv;
  7 using namespace std;
  8
  9 int main(int argc, char**argv)
 10 {
 11     Mat input_image;
 12     input_image = imread("car.jpg");
 13     if (input_image.data == NULL) {
 14         return -1; cout << "can‘t open image.../";
 15     }
 16     //-----------------------------------------------------------------------------------//
 17     //------------------------------梯度检测图像--------------------------------------//
 18     //-----------------------------------------------------------------------------------//
 19     Mat input_image1;
 20     input_image.copyTo(input_image1);
 21     cvtColor(input_image1, input_image1, CV_BGR2GRAY);
 22     input_image1.convertTo(input_image1, CV_32FC1);
 23     Mat sobelx = (Mat_<float>(3, 3) << -0.125, 0, 0.125, -0.25, 0, 0.25, -0.125, 0, 0.125);
 24     filter2D(input_image1, input_image1, input_image1.type(), sobelx);
 25     Mat mul_image;
 26     multiply(input_image1, input_image1, mul_image);
 27     const int scaleValue = 4;
 28     double threshold = scaleValue * mean(mul_image).val[0];//4 * img_s的平均值
 29     Mat resultImage = Mat::zeros(mul_image.size(), mul_image.type());
 30     float* pDataimg_s  = (float*)(mul_image.data);
 31     float* pDataresult = (float*)(resultImage.data);
 32     const int height = input_image1.rows;
 33     const int width  = input_image1.cols;
 34     //--- 非极大值抑制 + 阈值分割
 35     for (size_t i = 1; i < height-1; i++)
 36     {
 37         for (size_t j = 1; j < width-1; j++)
 38         {
 39             bool b1 = (pDataimg_s[i*height + j] > pDataimg_s[i*height + j - 1]);
 40             bool b2 = (pDataimg_s[i*height + j] > pDataimg_s[i*height + j + 1]);
 41             bool b3 = (pDataimg_s[i*height + j] > pDataimg_s[(i - 1)*height + j]);
 42             bool b4 = (pDataimg_s[i*height + j] > pDataimg_s[(i + 1)*height + j]);
 43             pDataresult[i*height + j] = 255 * ((pDataimg_s[i*height + j] > threshold) && ((b1&&b2) || (b3&&b4)));
 44         }
 45     }
 46     resultImage.convertTo(resultImage, CV_8UC1);
 47     //-----------------------------------------------------------------------------------//
 48     //---------------------------------HSV通道提取---------------------------------------//
 49     //-----------------------------------------------------------------------------------//
 50     Mat input_image2;
 51     input_image.copyTo(input_image2);
 52     Mat img_h, img_s, img_v, img_hsv;
 53     cvtColor(input_image2, img_hsv, CV_BGR2HSV);
 54     vector<Mat> hsv_vec;
 55     split(img_hsv, hsv_vec);
 56     img_h = hsv_vec[0];
 57     img_s = hsv_vec[1];
 58     img_v = hsv_vec[2];
 59     img_h.convertTo(img_h, CV_32F);
 60     img_s.convertTo(img_s, CV_32F);
 61     img_v.convertTo(img_v, CV_32F);
 62     normalize(img_h, img_h, 0, 1, NORM_MINMAX);
 63     normalize(img_s, img_s, 0, 1, NORM_MINMAX);
 64     normalize(img_v, img_v, 0, 1, NORM_MINMAX);
 65     //----下面的操作等同上面的归一化--------//
 66     //double h_max, s_max, v_max;
 67     ////minMaxIdx(img_h, 0, &h_max);
 68     //minMaxLoc(img_h, 0, &h_max);
 69     //minMaxLoc(img_s, 0, &s_max);
 70     //minMaxLoc(img_v, 0, &v_max);
 71     //img_h /= h_max;
 72     //img_s /= s_max;
 73     //img_v /= v_max;
 74     Mat img_vblue = ((img_h > 0.45)&(img_h < 0.75)&(img_s > 0.15)&(img_v > 0.25));//蓝色通道提取
 75     Mat vbule_gradient = Mat::zeros(input_image2.size(), CV_8UC1);
 76     for (size_t i = 1; i < height-1; i++)
 77     {
 78         for (size_t j = 1; j < width-1; j++)
 79         {
 80             /*Rect rec;
 81             rec.x = j - 1;
 82             rec.y = i - 1;
 83             rec.width  = 3;
 84             rec.height = 3;*/
 85             //----梯度和蓝色区域重合的部分,也可以用上面的矩形3X3的判断
 86             vbule_gradient.at<uchar>(i, j) = (resultImage.at<uchar>(i, j) == 255 && img_vblue.at<uchar>(i,j) != 0) ? 255 : 0;
 87             //vbule_gradient.at<uchar>(i, j) = (resultImage.at<uchar>(i, j) == 255 && countNonZero(img_vblue(rec)) >= 1) ? 255 : 0;
 88         }
 89     }
 90     //-----------------------------------------------------------------------------------//
 91     //-----------------------------形态学+轮廓提取车牌-----------------------------------//
 92     //-----------------------------------------------------------------------------------//
 93     Mat morph;
 94     morphologyEx(vbule_gradient, morph, MORPH_CLOSE, Mat::ones(2, 25, CV_8UC1));
 95     vector<vector<Point>> contours;
 96     vector<Vec4i> hierarchy;
 97     findContours(morph, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(-1, -1));
 98     Rect rec_adapt;
 99     for (size_t i = 0; i < contours.size(); i++)
100     {
101         //----矩形区域非零像素占总的比例,防止有较大的空白区域干扰检测结果
102         //----矩形的长宽限制,也可以再增加额外条件:长宽比例等
103         int true_pix_count = countNonZero(morph(boundingRect(contours[i])));
104         double true_pix_rate = static_cast<double>(true_pix_count) / static_cast<double>(boundingRect(contours[i]).area());
105         if (boundingRect(contours[i]).height > 10 && boundingRect(contours[i]).width > 80 && true_pix_rate > 0.7)
106         {
107             rec_adapt = boundingRect(contours[i]);
108             drawContours(morph, contours, static_cast<int>(i), Scalar(255, 255, 255), 2);
109         }
110     }
111     imshow("Area Brand", input_image(rec_adapt));
112     waitKey(0);
113     return 0;
114 }
115 #endif

参考:《opencv图像处理编程实例》

时间: 2024-10-29 19:05:58

《opencv实战》 之 车牌定位的相关文章

OpenCV使用边缘提取、腐蚀、轮廓进行车牌定位

采用OpenCV249利用边缘检测.轮廓检测.腐蚀实现的车牌定位,具体为: Mat srcImage=imread("image/000.jpg"); //imshow("a",srcImage); int i,j; int cPointR,cPointG,cPointB,cPoint;//currentPoint; Mat resizeImage; resize(srcImage,resizeImage,Size(400,300)); Mat grayImage;

EasyPR--中文开源车牌识别系统 开发详解(2)车牌定位

这篇文章是一个系列中的第三篇.前两篇的地址贴下:介绍.详解1.我撰写这系列文章的目的是:1.普及车牌识别中相关的技术与知识点:2.帮助开发者了解EasyPR的实现细节:3.增进沟通. EasyPR的项目地址在这:GitHub.要想运行EasyPR的程序,首先必须配置好openCV,具体可以参照这篇文章. 在前两篇文章中,我们已经初步了解了EasyPR的大概内容,在本篇内容中我们开始深入EasyRP的程序细节.了解EasyPR是如何一步一步实现一个车牌的识别过程的.根据EasyPR的结构,我们把它

汽车车牌定位识别系统的设计实现

http://www.eeworld.com.cn/qrs/2015/1023/article_25403.html 一.项目背景及可行性分析 2.1 项目背景及技术难点 项目名称:智能交通:汽车车牌定位识别: 项目内容:本项目是在FPGA前端实时完成图像采集.预处理.车牌定位和字符分割以及数据传输工作,在后端完成车牌字符识别工作.FPGA接收采集的实时图像,在内部采用流水线方式依次完成图像预处理.车牌定位和车牌字符分割工作,最后通过高速USB端口将已分割字符传输到后端进行字符识别.其中,图像采

车牌定位--颜色分割

http://blog.csdn.net/liujia2100/article/details/30845493 车牌定位是车牌识别中第一步,也是最重要的一步. 由于中国车牌种类多样,颜色不一, 再加上车牌经常有污损,以及车牌周围干扰因素太多,都成为了车牌定位的难点. 这里首先使用最简单算法来描述车牌定位,以及他的缺陷和改进. 一.投影法 1.车辆图像信息获取 2.HSV颜色转换 把RGB数据转换成HSV空间图像数据 hsvzation(image,hsv,width,height); 3.HS

基于matlab的蓝色车牌定位与识别---识别

接着昨天的工作,把最后一部分识别讲完. 关于字符识别这块,一种最省事的办法是匹配识别,将所得的字符和自己的标准字符库相减,计算所得结果,值最小的即为识别的结果.不过这种方法是在所得字符较为标准的情况,由于众多因素影响,切割出来的字符往往不是标准的,因此识别效果也不好.本次采用的BP神经网络方法,至于像其他的分类器方法,没有尝试,这里就不说了. 利用神经网络的方法的思路也比较清晰,将已有的字符库输入到神经网络的输入口进行训练,然后用训练好的神经网络对待识别的字符继续识别,输出识别结果.matlab

【原】基于matlab的蓝色车牌定位与识别---绪论

本着对车牌比较感兴趣,自己在课余时间摸索关于车牌的定位与识别,现将自己所做的一些内容整理下,也方便和大家交流. 考虑到车牌的定位涉及到许多外界的因素,因此有必要对车牌照的获取条件进行一些限定: 一.大部分车牌照都是用自己的手机照的,大小在1M左右,距离车牌照距离3m左右.这样保证所获取的车牌照有一定的规律,否则随便一张是无法进行定位的. 二.本次仅针对蓝色车牌,至于其他像黄色,黑色车牌的没有做研究.感兴趣的可以自己找些资料,毕竟要做到全面,工作量还是很大的. 三. 相关的参考资料网上也挺多的,这

逆向实战干货,快速定位自动捡阳光Call,或者标志

逆向实战干货,快速定位自动捡阳光Call,或者标志 注意: 关于CE和OD的使用,这里不再多说,快速定位,默认大家已经有了CE基础,或者OD基础. 第一种方法,找Call 第一步,打开CE,搜索阳光值 第二步,打开OD,数据窗口中搜索这个地址的数值(073B7C10) 注意,OD要先附加一下 F9 把游戏运行起来,我们数据窗口搜索这个地址的数值 然后找到地址 第三步,对其里面的值下内存写入断点 然后回到游戏,捡起一个阳光 内存断点断下来了,我们看下指令,发现 add函数,而且看下ECX的值 16

OpenCV学习之路——车牌识别之车牌定位

去年七月份因为学校项目需要开始接触图像处理,但那时候只是到网上找车牌识别代码,然后加入到自己的项目中,不清楚细节原理. 现在自己重新一步步实现车牌识别. 高斯模糊: 1 Mat Gaussian(Mat &img) { 2 Mat out; 3 GaussianBlur(img, out, Size(3, 3), 4 0, 0, BORDER_DEFAULT); 5 return out; 6 7 } 灰度化: 1 Mat Grayscale(Mat &img) { 2 Mat out;

车牌识别(一)-车牌定位

在对车牌识别过程中,常用的方法有:基于形状.基于色调.基于纹理.基于文字特征等方法.首先基于形状,在车牌中因为车牌为形状规格的矩形,所以目的转化为寻找矩形特征,常常是利用车牌长宽比例特征.占据图像的比例等.基于色调,国内的车牌往往是蓝底白字,可以采用图像的色调或者饱和度特征,进入生成二值图,定位车牌位置.基于纹理特征自己还没有基础到.基于文字特征往往是根据文字轮廓特征进行识别,原理是基于相邻文字轮廓特征.比例进行定位车牌位置. 一.图像二值化 正如前面文章所言,首先进行获取图像二值化特征,本文采