Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Normalize car plate for OCR in OpenCV C++

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:

floodfill

Hough

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

enter image description here

  1. After some transformation i need to get something like this: enter image description here

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

like image 552
pavel_s Avatar asked Feb 06 '15 03:02

pavel_s


People also ask

Can OCR read number plates?

Automatic Number Plate Recognition – or as it is frequently called “license plate recognition” – is a special form of optical character recognition (OCR), which enables computer systems to read out automatically the registration number (license plate number) of vehicles from a digital pictures.

How do I pull a number plate from a picture?

Step #1: Detect and localize a license plate in an input image/frame. Step #2: Extract the characters from the license plate. Step #3: Apply some form of Optical Character Recognition (OCR) to recognize the extracted characters.

Which algorithm is used for number plate detection?

LPR algorithm consists of the following three processing steps: 1) Number plate detection, 2) Character segmentation, and 3) Character recognition. The accuracy of plate extraction relies on the character segmentation and character recognition.


1 Answers

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:
enter image description here
enter image description here
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:
enter image description 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.

like image 86
cyriel Avatar answered Sep 29 '22 21:09

cyriel