一、简介

对车牌颜色进行识别,可能大部分人首先想到的是RGB模型, 但是此处RGB模型有一定的局限性,譬如蓝色,其值是255,还需要另外两个分量都为0,不然很有可能你得到的值是白色。黄色更麻烦,它是由红色和绿色组合而成的,这意味着你需要考虑两个变量的配比问题。这些问题让选择 RGB 模型进行判断的难度大到难以接受的地步。

HSV(Hue, Saturation, Value)是根据颜色的直观特性创建的一种颜色空间,也称六角锥体模型(Hexcone Model)。这个模型中颜色的参数分别是:色度(H),饱和度(S),亮度(V)。
  • 色度H:用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。
  • 饱和度S:取值范围为0.0~1.0;
  • 亮度V:取值范围为0.0(黑色)~1.0(白色)。
RGB和CMY颜色模型都是面向硬件的,而HSV(Hue Saturation Value)颜色模型是面向用户的。
HSV模型的三维表示从RGB立方体演化而来。设想从RGB沿立方体对角线的白色顶点向黑色顶点观察,就可以看到立方体的六边形外形。六边形边界表示色彩,水平轴表示纯度,明度沿垂直轴测量。

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() ,具体代码如下所示

int CPlateLocate::plateColorLocate(Mat src, vector<CPlate> &candPlates,int index) {
vector<RotatedRect> rects_color_blue;
rects_color_blue.reserve();
vector<RotatedRect> rects_color_yellow;
rects_color_yellow.reserve(); vector<CPlate> plates_blue;
plates_blue.reserve();
vector<CPlate> plates_yellow;
plates_yellow.reserve(); 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 ;
}

这里为了加快计算机的计算速率,采用了OpenMP技术,OpenMP是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受,用于共享内存并行系统的多处理器程序设计的一套指导性编译处理方案。通过并行计算,分别进行蓝色和黄色车牌的处理。其中两个主要处理函数 colorSearch() deskew()分别对图片进行颜色匹配和偏斜扭转。

colorSearch()主要是根据上文介绍的HSV模型,进行相关颜色定位,然后依据常见的图像处理方法进行处理,例如阈值分割,形态学处理和轮廓查找等。具体代码如下所示:

 int CPlateLocate::colorSearch(const Mat &src, const Color r, Mat &out,
vector<RotatedRect> &outRects) {
Mat match_grey; // width is important to the final results; const int color_morph_width = ;
const int color_morph_height = ; colorMatch(src, match_grey, r, false); Mat src_threshold;
threshold(match_grey, src_threshold, , ,
CV_THRESH_OTSU + CV_THRESH_BINARY); Mat element = getStructuringElement(
MORPH_RECT, Size(color_morph_width, color_morph_height));
morphologyEx(src_threshold, src_threshold, MORPH_CLOSE, element); src_threshold.copyTo(out); vector<vector<Point>> contours; findContours(src_threshold,
contours, // a vector of contours
CV_RETR_EXTERNAL,
CV_CHAIN_APPROX_NONE); // all pixels of each contours vector<vector<Point>>::iterator itc = contours.begin();
while (itc != contours.end()) {
RotatedRect mr = minAreaRect(Mat(*itc)); if (!verifySizes(mr))
itc = contours.erase(itc);
else {
++itc;
outRects.push_back(mr);
}
} return ;
}

EasyPR中的colorMatch()函数比较复杂,读者可以简单理解为用inRange函数对图像hsv空间进行处理,得到颜色过滤后的图像。(其实colotMatch函数中对hsv模型中的s和v根据h的值进行自适应变化),进行阈值分割后,采用了形态学图像处理,内核为一个 10X2矩形,需要注意的是,内核的大小对最终的结果有很大的影响。对寻找到的轮廓,先进性尺寸验证,不符合尺寸的轮廓直接去除。尺寸验证调用函数 verifySizes() 。尺寸验证函数主要是对轮廓的长度和宽度,还有长宽比做了限制,以过滤掉大部分的明显非车牌的轮廓区域。

EasyPR源码剖析(3):车牌定位之颜色定位的更多相关文章

  1. EasyPR源码剖析(5):车牌定位之偏斜扭转

    一.简介 通过颜色定位和Sobel算子定位可以计算出一个个的矩形区域,这些区域都是潜在车牌区域,但是在进行SVM判别是否是车牌之前,还需要进行一定的处理.主要是考虑到以下几个问题: 1.定位区域存在一 ...

  2. EasyPR源码剖析(2):车牌定位

    上一篇主要介绍了车牌识别的整体框架和流程,车牌识别主要划分为了两个过程:即车牌检测和字符识别,而车牌识别的核心环节就是这一节主要介绍的车牌定位,即 Plate Locate.车牌定位主要是将图片中有可 ...

  3. EasyPR源码剖析(1):概述

    EasyPR(Easy to do Plate Recognition)是本人在opencv学习过程中接触的一个开源的中文车牌识别系统,项目Git地址为https://github.com/liuru ...

  4. EasyPR源码剖析(4):车牌定位之Sobel算子定位

    一.简介 sobel算子主要是用于获得数字图像的一阶梯度,常见的应用是边缘检测. Ⅰ.水平变化: 将 I 与一个奇数大小的内核进行卷积.比如,当内核大小为3时, 的计算结果为: Ⅱ.垂直变化: 将: ...

  5. EasyPR源码剖析(7):车牌判断之SVM

    前面的文章中我们主要介绍了车牌定位的相关技术,但是定位出来的相关区域可能并非是真实的车牌区域,EasyPR通过SVM支持向量机,一种机器学习算法来判定截取的图块是否是真的“车牌”,本节主要对相关的技术 ...

  6. EasyPR源码剖析(6):车牌判断之LBP特征

    一.LBP特征 LBP指局部二值模式,英文全称:Local Binary Pattern,是一种用来描述图像局部特征的算子,LBP特征具有灰度不变性和旋转不变性等显著优点. 原始的LBP算子定义在像素 ...

  7. EasyPR源码剖析(8):字符分割

    通过前面的学习,我们已经可以从图像中定位出车牌区域,并且通过SVM模型删除“虚假”车牌,下面我们需要对车牌检测步骤中获取到的车牌图像,进行光学字符识别(OCR),在进行光学字符识别之前,需要对车牌图块 ...

  8. EasyPR源码剖析(9):字符识别

    在上一篇文章的介绍中,我们已经通过相应的字符分割方法,将车牌区域进行分割,得到7个分割字符图块,接下来要做的就是将字符图块放入训练好的神经网络模型,通过模型来预测每个图块所表示的具体字符.神经网络的介 ...

  9. HashMap源码剖析

    HashMap源码剖析 无论是在平时的练习还是项目当中,HashMap用的是非常的广,真可谓无处不在.平时用的时候只知道HashMap是用来存储键值对的,却不知道它的底层是如何实现的. 一.HashM ...

随机推荐

  1. Laravel发送邮箱消息验证

    945的密码:umywcvkrfrytfeef ENV的配置如下: MAIL_DRIVER=smtpMAIL_HOST=smtp.qq.comMAIL_PORT=25MAIL_USERNAME=XXX ...

  2. Rabbitmq 安装后采坑

    一.接手项目 接手项目后,按别人说的先安装什么,后安装什么然后就可以用了,也不去看什么.先开始安装的是otp_win64_19.1工具包和rabbitmq-server-3.6.5服务端,在win10 ...

  3. python远程连接windows

    远程连接windows系统     https://blog.51cto.com/ckl893/2145809 import winrm win2008 = winrm.Session('http:/ ...

  4. Verilog笔记——Verilog数字系统设计(第二版)夏宇闻

    本片记录Verilog学习笔记,主要是和以往用的C语言的不同之处,以例子.代码的形式记录.学习以<Verilog数字系统设计>(第二版)为参考资料,援助作者夏宇闻. 1. C语言和Veri ...

  5. activiti官网实例项目activiti-explorer之扩展流程节点属性

    节点中添加“关联表单”属性 1,stencilset.json中加入如下代码 , {    "name" : "approveTypepackage",    ...

  6. Fiddler手机抓包设置

    前提条件:1).电脑需要安装Fiddler2).测试手机需要支持Wifi3).测试手机与电脑需要同一网络4).所测APP需支持代理 三.设置Fiddler 1.(1)电脑端打开安装好的的fiddler ...

  7. 鱼骨时间轴案例(转自CSDN,原文链接附于文中)

    $.fn.fishBone = function(data) { var colors = ['#F89782','#1A84CE']; /**入口*/ //1.创建dom $(this).child ...

  8. Linux NGINX部署

    一.Nginx简介 Nginx是一个web服务器也可以用来做负载均衡及反向代理使用,目前使用最多的就是负载均衡,具体简介我就不介绍了百度一下有很多,下面直接进入安装步骤 二.Nginx安装 1.下载N ...

  9. kafka创建会话,报Error while executing topic command : Replication factor: 1 larger than available brokers: 0.

     bin/kafka-topics.sh --create --zookeeper es1:2181 --replication-factor 1 --partitions 1 --topic top ...

  10. 关于d3.js 将一个element 拖拽到另一个element的响应事件

    rt 正在做机柜可视化, 一个需求是能拖拽左侧列表的设备名称, 拖到右侧42U机柜中,并将设备图片放置在对应机柜位置上. 开始的时候一切都很顺利,点击左侧设备名称,添加一个g容器,将设备名称作为tex ...