EasyPR-Java新能源車牌識別
阿新 • • 發佈:2019-01-08
EasyPR中主要涉及到藍色底牌與黃色底牌的車牌識別,隨著新能源車輛的發展,目前已經出現綠色底牌的車牌,因此有必要增加綠色車牌的識別。
EasyPR中關於車牌的識別,已經比較完善,這裡主要涉及到三個地方的修改。
新增顏色
在自定義Color的列舉類中,新增 綠色,修改之後為:
public enum Color {
UNKNOWN, BLUE, YELLOW, GREEN
};
新增綠色識別
在OpenCV或其他軟體中,識別顏色主要通過RGB對映到HSV空間,通過判斷H、S、V的相關值來判斷顏色的,主要原理可以參考:OpenCV顏色識別。修改之後的部分程式碼如下:
public static Mat colorMatch(final Mat src, final Color r,
final boolean adaptive_minsv) {
final float max_sv = 255;
final float minref_sv = 40;
final float minabs_sv = 60;
// blue的H範圍75-130
final int min_blue = 100;
final int max_blue = 140;
// yellow的H範圍22- 38
final int min_yellow = 10;
final int max_yellow = 35;
// green的H範圍38-75// -- 增加綠色判斷範圍 --
final int min_green = 35;
final int max_green = 80;
// 轉到HSV空間進行處理,顏色搜尋主要使用的是H分量進行藍色與黃色、綠色的匹配工作
Mat src_hsv = new Mat();
cvtColor(src, src_hsv, CV_BGR2HSV);
MatVector hsvSplit = new MatVector();
split(src_hsv, hsvSplit);
equalizeHist(hsvSplit.get(2), hsvSplit.get(2));
merge(hsvSplit, src_hsv);
// 匹配模板基色,切換以查詢想要的基色
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 GREEN:
min_h = min_green;
max_h = max_green;
default:
break;
}
float diff_h = (float) ((max_h - min_h) / 2);
int avg_h = (int) (min_h + diff_h);
int channels = src_hsv.channels();
int nRows = src_hsv.rows();
// 影象資料列需要考慮通道數的影響;
int nCols = src_hsv.cols() * channels;
// 連續儲存的資料,按一行處理
if (src_hsv.isContinuous()) {
nCols *= nRows;
nRows = 1;
}
for (int i = 0; i < nRows; ++i) {
BytePointer p = src_hsv.ptr(i);
for (int j = 0; j < nCols; j += 3) {
int H = p.get(j) & 0xFF;
int S = p.get(j + 1) & 0xFF;
int V = p.get(j + 2) & 0xFF;
boolean colorMatched = false;
if (H > min_h && H < max_h) {
int Hdiff = 0;
if (H > avg_h)
Hdiff = H - avg_h;
else
Hdiff = avg_h - H;
float Hdiff_p = Hdiff / diff_h;
float min_sv = 0;
if (true == adaptive_minsv)
min_sv = minref_sv - minref_sv / 2 * (1 - Hdiff_p);
else
min_sv = minabs_sv;
if ((S > min_sv && S <= max_sv)
&& (V > min_sv && V <= max_sv))
colorMatched = true;
}
if (colorMatched == true) {
p.put(j, (byte) 0);
p.put(j + 1, (byte) 0);
p.put(j + 2, (byte) 255);
} else {
p.put(j, (byte) 0);
p.put(j + 1, (byte) 0);
p.put(j + 2, (byte) 0);
}
}
}
// 獲取顏色匹配後的二值灰度圖
MatVector hsvSplit_done = new MatVector();
split(src_hsv, hsvSplit_done);
Mat src_grey = hsvSplit_done.get(2);
return src_grey;
}
增加字元限制
以前的車牌主要是7位字元,包括省 [A-Z].[5位字元] 的方式。但新能源車牌,後面5為字元變為6位字元,因此之前的判斷方法不能夠獲取全部車牌,最好的情況也只能獲得前面的7位字元。因此需要修改為:
private int RebuildRect(final Vector<Rect> vecRect, Vector<Rect> outRect,
int specIndex) {
// 最大隻能有7個Rect,減去中文的就只有6個Rect
int count = 7;// --這裡將6修改為7即可--
for (int i = 0; i < vecRect.size(); i++) {
// 將特殊字元左邊的Rect去掉,這個可能會去掉中文Rect,不過沒關係,我們後面會重建。
if (i < specIndex)
continue;
outRect.add(vecRect.get(i));
if (--count == 0)
break;
}
return 0;
}
至此,可以識別綠色車牌。