EasyPR源码剖析(3):车牌定位之颜色定位
一、简介
对车牌颜色进行识别,可能大部分人首先想到的是RGB模型, 但是此处RGB模型有一定的局限性,譬如蓝色,其值是255,还需要另外两个分量都为0,不然很有可能你得到的值是白色。黄色更麻烦,它是由红色和绿色组合而成的,这意味着你需要考虑两个变量的配比问题。这些问题让选择 RGB 模型进行判断的难度大到难以接受的地步。
- 色度H:用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。
- 饱和度S:取值范围为0.0~1.0;
- 亮度V:取值范围为0.0(黑色)~1.0(白色)。
![](https://images2015.cnblogs.com/blog/1022301/201707/1022301-20170725193123654-315364020.png)
H 分量是 HSV 模型中唯一跟颜色本质相关的分量。 只要固定了 H 的值, 并且保持 S 和 V 分量不太小,那么表现的颜色就会基本固定。
一般对颜色空间的图像进行有效处理都是在HSV空间进行的,然后对于基本色中对应的HSV分量需要给定一个严格的范围,下面是通过实验计算的模糊范围(准确的范围在网上都没有给出)。
H: 0— 180
S: 0— 255
V: 0— 255
读取一张图片或从视频读取一帧图像,可以用下面的函数转为HSV模型。
cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV);
然后对彩色图像做直方图均衡化,因为读取的是彩色图,直方图均衡化需要在HSV空间中进行。
split(imgHSV, hsvSplit); equalizeHist(hsvSplit[2],hsvSplit[2]); merge(hsvSplit,imgHSV);
接着就是进行颜色检测
inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded);
inRange()函数进行颜色检测,这个函数的作用就是检测src图像的每一个像素是不是在lowerb和upperb之间,如果是,这个像素就设置为255,并保存在dst图像中,否则为0。
二、颜色定位
颜色定位主要处理函数为 plateColorLocate() ,具体代码如下所示
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int CPlateLocate::plateColorLocate(Mat src, vector<CPlate> &candPlates,int index) { vector<RotatedRect> rects_color_blue; rects_color_blue.reserve(64); vector<RotatedRect> rects_color_yellow; rects_color_yellow.reserve(64); vector<CPlate> plates_blue; plates_blue.reserve(64); vector<CPlate> plates_yellow; plates_yellow.reserve(64); Mat src_clone = src.clone(); Mat src_b_blue; Mat src_b_yellow; #pragma omp parallel sections { #pragma omp section { colorSearch(src, BLUE, src_b_blue, rects_color_blue); deskew(src, src_b_blue, rects_color_blue, plates_blue, true, BLUE); } #pragma omp section { colorSearch(src_clone, YELLOW, src_b_yellow, rects_color_yellow); deskew(src_clone, src_b_yellow, rects_color_yellow, plates_yellow, true, YELLOW); } } candPlates.insert(candPlates.end(), plates_blue.begin(), plates_blue.end()); candPlates.insert(candPlates.end(), plates_yellow.begin(), plates_yellow.end()); return 0; }
这里为了加快计算机的计算速率,采用了OpenMP技术,OpenMP是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受,用于共享内存并行系统的多处理器程序设计的一套指导性编译处理方案。通过并行计算,分别进行蓝色和黄色车牌的处理。其中两个主要处理函数 colorSearch() 和 deskew()分别对图片进行颜色匹配和偏斜扭转。
colorSearch()主要是根据上文介绍的HSV模型,进行相关颜色定位,然后依据常见的图像处理方法进行处理,例如阈值分割,形态学处理和轮廓查找等。具体代码如下所示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 int CPlateLocate::colorSearch(const Mat &src, const Color r, Mat &out, 2 vector<RotatedRect> &outRects) { 3 Mat match_grey; 4 5 // width is important to the final results; 6 7 const int color_morph_width = 10; 8 const int color_morph_height = 2; 9 10 colorMatch(src, match_grey, r, false); 11 12 13 Mat src_threshold; 14 threshold(match_grey, src_threshold, 0, 255, 15 CV_THRESH_OTSU + CV_THRESH_BINARY); 16 17 Mat element = getStructuringElement( 18 MORPH_RECT, Size(color_morph_width, color_morph_height)); 19 morphologyEx(src_threshold, src_threshold, MORPH_CLOSE, element); 20 21 src_threshold.copyTo(out); 22 23 24 vector<vector<Point>> contours; 25 26 findContours(src_threshold, 27 contours, // a vector of contours 28 CV_RETR_EXTERNAL, 29 CV_CHAIN_APPROX_NONE); // all pixels of each contours 30 31 vector<vector<Point>>::iterator itc = contours.begin(); 32 while (itc != contours.end()) { 33 RotatedRect mr = minAreaRect(Mat(*itc)); 34 35 if (!verifySizes(mr)) 36 itc = contours.erase(itc); 37 else { 38 ++itc; 39 outRects.push_back(mr); 40 } 41 } 42 43 return 0; 44 }
EasyPR中的colorMatch()函数比较复杂,读者可以简单理解为用inRange函数对图像hsv空间进行处理,得到颜色过滤后的图像。(其实colotMatch函数中对hsv模型中的s和v根据h的值进行自适应变化),进行阈值分割后,采用了形态学图像处理,内核为一个 10X2矩形,需要注意的是,内核的大小对最终的结果有很大的影响。对寻找到的轮廓,先进性尺寸验证,不符合尺寸的轮廓直接去除。尺寸验证调用函数 verifySizes() 。尺寸验证函数主要是对轮廓的长度和宽度,还有长宽比做了限制,以过滤掉大部分的明显非车牌的轮廓区域。
posted on 2017-07-27 15:36 freedomker 阅读(6110) 评论(3) 编辑 收藏 举报