1. 程式人生 > >EasyPR-Java新能源車牌識別

EasyPR-Java新能源車牌識別

  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;
}

至此,可以識別綠色車牌。