在 OpenCV C++ 中为 OCR 规范化车牌

Posted

技术标签:

【中文标题】在 OpenCV C++ 中为 OCR 规范化车牌【英文标题】:Normalize car plate for OCR in OpenCV C++ 【发布时间】:2015-04-06 03:06:56 【问题描述】:

我正在做一些简单的 OCR 车牌识别系统。我正在使用 HaarCascades 来查找车牌,接下来我需要对这个车牌进行归一化,以将其放入我的 OCR 模块中。我正在使用 Floodfill 来查找车牌的主要轮廓,然后执行 Hough 变换,以查找车牌的上下边界:

这是我执行霍夫变换的部分代码^

HoughLinesP(canny_img, lines, 1, CV_PI/180, 80, 80, 30 );

    for ( size_t i = 0; i < lines.size(); i++ )   
        line (output, Point(lines[i][0], lines[i][3]), Point(lines[i][4], lines[i][5]), Scalar(0,0,255), 1, 8 );
    

现在我需要沿着这两条线剪切和旋转这张图片。我怎样才能做到这一点?我知道我需要使用点 Point(lines[i][0])..Point(linesi),但我应该如何处理它们?

所以基本上,我需要得到类似的东西:

    图片,我使用 HaarCascades 得到的

    经过一些改造,我需要得到这样的东西:

所以第一步我只需要切割上下边界。

【问题讨论】:

你也需要纠正透视失真吗? 【参考方案1】:

你需要使用仿射变换,这里有tutorial。在您的情况下,您需要选择一些尺寸的车牌,例如20x100。您的目标点将是选定大小的非旋转矩形的 3 个角,源点将是已创建车牌的 3 个角。我希望很清楚,如果不是,请告诉我——我会举一些例子。

*\\编辑: 好的,我做了一些例子。这是代码:

cv::Mat img = cv::imread("D:\\temp\\car_plate.jpg");
cv::Point2f a1(25, 18), b1(279, 27), c1(279, 79), a2(0, 0), b2(img.size().width, 0), c2(img.size().width, img.size().height);
//cv::Point2f a1(0, 16), b1(303, 28), c1(303, 81), a2(0, 0), b2(img.size().width, 0), c2(img.size().width, img.size().height);
cv::Point2f src[] = a1, b1, c1;
cv::Point2f dst[] = a2, b2, c2;
cv::Mat warpMat = cv::getAffineTransform(src, dst);
cv::warpAffine(img, img, warpMat, img.size());
cv::imshow("result", img);
cv::waitKey(-1);
return 0;

结果: 如果您不加任何修改地使用代码,您将获得第一个结果,如果您评论第二行并取消评论第三行,您将获得第二个结果(我认为这就是您想要的)。要获得第二个结果,您只需要找到上下线穿过图像边界的点。我在这里标记了: 所以基本上你需要使用红点。要计算它们的位置,您只需要找到蓝线(如果我理解正确,您已经有)穿过图像边界的位置。

【讨论】:

感谢您的回答!我添加了另外两张图片来解释我需要什么。据我了解,您建议我将切割全车板的方法,但基本上我只需要切割上下边界。对不起我的英语。 非常感谢!这就是我所需要的! 要纠正透视失真(在最终图像中作为空白或缺失部分很明显),请使用getPerspectiveTransformwarpPerspective。有了这个,您需要传入图像所有 4 个角的坐标。【参考方案2】:

这是 EmguCv 的解决方案:

var src = new[]  new PointF(approxContour[0].X, approxContour[0].Y), new PointF(approxContour[1].X, approxContour[1].Y), new PointF(approxContour[2].X, approxContour[2].Y), new PointF(approxContour[3].X, approxContour[3].Y) ;
var dst = new[]  new PointF(0, 0), new PointF(0, 400), new PointF(400, 400), new PointF(400, 0) ;

var tmp = new UMat();
var matrix = CvInvoke.GetPerspectiveTransform(src, dst);
CvInvoke.WarpPerspective(imageRGB, tmp, matrix, new Size(400, 400));
viewer.Image = tmp;

【讨论】:

以上是关于在 OpenCV C++ 中为 OCR 规范化车牌的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV实现车牌识别,OCR分割,ANN神经网络

OpenCV实现车牌识别,OCR分割,ANN神经网络

C#车牌号码识别-基于百度OCR

技术解析: 手机车牌识别软件—移动端车牌识别/OCR算法

技术解析: 手机车牌识别软件—移动端车牌识别/OCR算法

技术解析: 手机车牌识别软件—移动端车牌识别/OCR算法