在OpenCV C ++中对OCR进行标准化 [英] Normalize car plate for OCR in OpenCV C++

查看:156
本文介绍了在OpenCV C ++中对OCR进行标准化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做一些简单的OCR车牌识别系统。我使用HaarCascades找到车板,接下来我需要标准化这个板,把它放到我的OCR模块。我使用洪水填充找到汽车板的主要轮廓,然后我执行霍夫变换,找到汽车板的上下边界:







这里是代码的一部分,我执行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])..点(行。在你的情况下,你需要选择一些尺寸的汽车板,例如 20x100 。您的目的地点将是选定尺寸的非旋转矩形的三个角,源点将是创建的车牌的三个角。我希望很清楚,如果它不是,让我知道 - 我会举一个例子。



* \\EDIT:

好​​,我举了一个例子。这是代码:

  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 (img.size()。width,img.size()。height);
// cv :: Point2f a1(0,16),b1(303,28),c1(303,81),a2(0,0),b2(img.size ,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;

结果:





如果您将使用代码而不进行任何修改,您将获得第一个结果,如果您注释第二行并取消注释第三行,您将获得第二个结果(我认为这是您想要的)。要获得第二个结果,您只需要找到上下线穿过图像边框的点。我已在此处标记:



所以基本上你需要使用红点。要计算他们的位置,你只需要找到蓝线(如果我理解正确你已经有)跨图像边框。


I'm doing some simple OCR car plate recognition system. I'm using HaarCascades to find car plate, and next i need to normalize this plate, to put it into my OCR module. I'm using floodfill to find main contours of a car plate, and then i perform Hough transform, to find upper and lower boarders of a car plate:

Here's a part of code, where i perform Hough transform^

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

Now i need to cut and rotate this picture along this two lines. How can i do this? i understand that i need to use point Point(lines[i][0])..Point(linesi), but what i should do with them?

So basically, i need to get something like that:

  1. Image, that i got using HaarCascades

  1. After some transformation i need to get something like this:

So at the first step i need to cut only upper and lower boarders.

解决方案

You need to use affine transformations, here there is tutorial. In your situation you need to choose some size of car plate, for example 20x100. Your destination points will be 3 corners of non rotated rectangle of choosen size and source points will be 3 corners of founded car plate. I hope it is clear, if it is'not, let me know - i will make some example.

*\\EDIT:
Ok, i've made some example. Here is the code:

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;

And results:


If you will use the code without any modification you will get the first result, if you comment second line and uncomment third line you will get second result (i think that's what you wanted). To get the second result you just need to find the points where upper and lower lines cross the image border. I've marked it here:

So basically you need to use red points. To calculate their positions you just need to find where blue lines (which if i understand correct you already have) cross the image border.

这篇关于在OpenCV C ++中对OCR进行标准化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆