新能源車車牌識別c++
阿新 • • 發佈:2019-01-02
EasyPR中主要涉及到藍色底牌與黃色底牌、白色底牌的車牌識別,隨著新能源車輛的發展,目前有很多綠色底牌的車牌,因此增加綠色車牌的識別。
EasyPR中關於車牌的識別,已經比較完善,這裡主要涉及到三個地方的修改。
1.新增顏色
include/easypr/config.h
在自定義Color的列舉類中,新增 綠色,修改之後為:
enum Color { BLUE, YELLOW, WHITE, GREEN, UNKNOWN };
新增綠色識別
在OpenCV或其他軟體中,識別顏色主要通過RGB對映到HSV空間,通過判斷H、S、V的相關值來判斷顏色的,主要原理可以參考:OpenCV顏色識別。修改之後的部分程式碼如下:
src/core/core_func.cpp
Mat colorMatch(const Mat &src, Mat &match, const Color r, const bool adaptive_minsv) { // if use adaptive_minsv // min value of s and v is adaptive to h const float max_sv = 255; const float minref_sv = 64; const float minabs_sv = 95; //95; // H range of blue const int min_blue = 100; // 100 const int max_blue = 140; // 140 // H range of yellow const int min_yellow = 15; // 15 const int max_yellow = 40; // 40 // H range of white const int min_white = 0; // 15 const int max_white = 30; // 40 //Louis add,green // H range of green const int min_green = 35; // 35 const int max_green = 80; // 80 Mat src_hsv; // convert to HSV space cvtColor(src, src_hsv, CV_BGR2HSV); std::vector<cv::Mat> hsvSplit; split(src_hsv, hsvSplit); equalizeHist(hsvSplit[2], hsvSplit[2]); merge(hsvSplit, src_hsv); // match to find the color int min_h = 0; int max_h = 0; switch (r) { case BLUE: min_h = min_blue; max_h = max_blue; break; case YELLOW: min_h = min_yellow; max_h = max_yellow; break; case WHITE: min_h = min_white; max_h = max_white; break; //Louis add,green case GREEN: min_h = min_green; max_h = max_green; break; default: // Color::UNKNOWN break; } float diff_h = float((max_h - min_h) / 2); float avg_h = min_h + diff_h; int channels = src_hsv.channels(); int nRows = src_hsv.rows; // consider multi channel image int nCols = src_hsv.cols * channels; if (src_hsv.isContinuous()) { nCols *= nRows; nRows = 1; } int i, j; uchar* p; float s_all = 0; float v_all = 0; float count = 0; for (i = 0; i < nRows; ++i) { p = src_hsv.ptr<uchar>(i); for (j = 0; j < nCols; j += 3) { int H = int(p[j]); // 0-180 int S = int(p[j + 1]); // 0-255 int V = int(p[j + 2]); // 0-255 s_all += S; v_all += V; count++; bool colorMatched = false; if (H > min_h && H < max_h) { float Hdiff = 0; if (H > avg_h) Hdiff = H - avg_h; else Hdiff = avg_h - H; float Hdiff_p = float(Hdiff) / diff_h; float min_sv = 0; if (true == adaptive_minsv) min_sv = minref_sv - minref_sv / 2 * (1 - Hdiff_p); // inref_sv - minref_sv / 2 * (1 - Hdiff_p) else min_sv = minabs_sv; // add if ((S > min_sv && S < max_sv) && (V > min_sv && V < max_sv)) colorMatched = true; } if (colorMatched == true) { p[j] = 0; p[j + 1] = 0; p[j + 2] = 255; } else { p[j] = 0; p[j + 1] = 0; p[j + 2] = 0; } } } // cout << "avg_s:" << s_all / count << endl; // cout << "avg_v:" << v_all / count << endl; // get the final binary Mat src_grey; std::vector<cv::Mat> hsvSplit_done; split(src_hsv, hsvSplit_done); src_grey = hsvSplit_done[2]; match = src_grey; return src_grey; }
其中RGB與HSV顏色識別對應的關係,可以參考:OpenCV中HSV顏色模型及顏色分量範圍
增加字元限制
以前的車牌主要是7位字元,包括省 [A-Z].[5位字元] 的方式。但新能源車牌,後面5為字元變為6位字元,因此之前的判斷方法不能夠獲取全部車牌,最好的情況也只能獲得前面的7位字元。因此需要修改為:
src/core/chars_segment.cpp
int CCharsSegment::RebuildRect(const vector<Rect>& vecRect, vector<Rect>& outRect, int specIndex) { int count = 7;//Louis changed 6->7, for green plate car for (size_t i = specIndex; i < vecRect.size() && count; ++i, --count) { outRect.push_back(vecRect[i]); } return 0; }
至此,可以識別綠色車牌。