一、簡介
對車牌顏色進行識別,可能大部分人首先想到的是RGB模型, 但是此處RGB模型有一定的局限性,譬如藍色,其值是255,還需要另外兩個分量都為0,不然很有可能你得到的值是白色。黃色更麻煩,它是由紅色和綠色組合而成的,這意味着你需要考慮兩個變量的配比問題。這些問題讓選擇 RGB 模型進行判斷的難度大到難以接受的地步。
- 色度H:用角度度量,取值范圍為0°~360°,從紅色開始按逆時針方向計算,紅色為0°,綠色為120°,藍色為240°。
- 飽和度S:取值范圍為0.0~1.0;
- 亮度V:取值范圍為0.0(黑色)~1.0(白色)。
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(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模型,進行相關顏色定位,然后依據常見的圖像處理方法進行處理,例如閾值分割,形態學處理和輪廓查找等。具體代碼如下所示:
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() 。尺寸驗證函數主要是對輪廓的長度和寬度,還有長寬比做了限制,以過濾掉大部分的明顯非車牌的輪廓區域。
