当前位置: 首页 > 工具软件 > EasyPR-Java > 使用案例 >

EasyPR-Java新能源车牌识别

陈宏胜
2023-12-01

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

其中RGB与HSV颜色识别对应的关系,可以参考:OpenCV中HSV颜色模型及颜色分量范围

增加字符限制

  以前的车牌主要是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;
}

至此,可以识别绿色车牌。

 类似资料: