License plate number identification based on opencv _ 2, opencv_2
Introduction
The previous article explains how to screen images in blue and then perform grayscale/binarization. Here we will continue to explain.
Rectangle Detection
Because the license plate is a rectangle. So we will expand the image after the binarization, and then conduct the rectangle detection. Select the rectangular area of the license plate number. The Code is as follows:
Int ** car_License_box (Mat & mat1, Mat & mat2, int * number) {Mat threshold_output; vector <Point> contours; vector <Vec4i> hierarchy; Point s1, s2; int width_1, height_1; int width = mat1.rows; int height = mat1.cols; int sum = 0; int morph_elem = 3; int morph_size = 3; int ** a = (int **) malloc (width * sizeof (int *); // corrode Mat element = getStructuringElement (MORPH_RECT, Size (2 * morph_size + 1, 2 * morph_size + 1), Point (-1,-1); dilate (mat1, mat1, element); // locate the findContours (mat1, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point (0, 0); // returns the approximate contour of a polygon + returns the vector <Point> contours_poly (contours. size (); vector <Rect> boundRect (ipvs. size (); vector <Point2f> center (contours. size (); vector <float> radius (ipvs. size (); for (int I = 0; I <contours. size (); I ++) {approxPolyDP (Mat (contours [I]), contours_poly [I], 3, true ); boundRect [I] = boundingRect (Mat (contours_poly [I]); minEnclosingCircle (contours_poly [I], center [I], radius [I]);} /// draw a polygon contour + a Rectangular Box surrounded by a rectangle + a circular box mat2 = Mat: zeros (mat1.size (), CV_8UC3); for (int I = 0; I <contours. size (); I ++) {s1 = boundRect [I]. tl (); s2 = boundRect [I]. br (); height_1 = s2.x-s1.x; width_1 = s2.y-s1.y; if (height_1> (3 * width_1) & (width_1> (width/2 ))) {a [sum] = (int *) malloc (4 * sizeof (int); a [sum] [0] = s1.x; a [sum] [1] = s1.y; a [sum] [2] = s2.x; a [sum] [3] = s2.y; sum + = 1 ;}} * number = sum; return ;} int main (int argc, char ** argv ){............. pic_gray (img_3, img_3); threshold = histogram_Calculate (img_3, 3); Round (img_3, threshold); address_1 = round (img_3, img_4, & struct); sprintf (str, "% d", I); namedWindow (str); imshow (str, img_3) ;}} waitKey (0); return 0 ;}
In the car_License_box function, img_3 is the input source image, and then an appropriate rectangle is detected. The corner points on the left and right of the rectangle are saved in address_1, a two-dimensional array, the number of detected rectangles is stored in address_Number_1. The specific process of this function is as follows: 1. Use dilate to expand the image. 2. Use the contour searched in the opencv tutorial and save the detected rectangular corner points in boundRect. 3. The width and height of the rectangle can be calculated based on the corner points on the left and bottom right of the rectangle. The rectangle where the license plate is located must be at least three times the width. At the same time, in the previously split image, the license plate width should be at least half of the image. 4. Save the rectangular corner points that meet the requirements in the two-dimensional array a, add the rectangular detection count + 1, and return the corresponding two-dimensional array.
Rectangular Segmentation
The above rectangle is separated, and it is possible that the rectangle position of the license plate is saved in address_1. Here, based on the coordinate of the Angle Point in address_1, copy the corresponding rectangle from the original image to the new image for display:
void pic_cutting_1(Mat& mat1, Mat& mat2, Point s1, Point s2){ int i, j; IplImage pI_1; IplImage pI_2; CvScalar s; mat2 = cv::Mat(s2.y - s1.y, s2.x - s1.x, CV_8UC3, 1); pI_1 = mat1; pI_2 = mat2; for(i = s1.y; i < s2.y; i++){ for(j=s1.x; j<s2.x; j++){ s = cvGet2D(&pI_1, i, j); cvSet2D(&pI_2, i-s1.y, j-s1.x, s); } }} int main(int argc, char** argv){ ..................... address_1 = car_License_box(img_3, img_4, &address_Number_1); for(j=0; j< address_Number_1; j++){ DE("address_0:%d, %d, %d, %d\n", address_1[j][0], address_1[j][1], address_1[j][2], address_1[j][3]); s1.y = address_1[j][1] + selection_1[i][0]; s1.x = address_1[j][0]; s2.y = address_1[j][1] + selection_1[i][1]; s2.x = address_1[j][2]; DE("address:%d, %d, %d, %d\n", s1.x, s1.y, s2.x, s2.y); pic_cutting_1(img, img_5, s1, s2); sprintf(str, "%d", j); namedWindow(str); imshow(str, img_5); } } } namedWindow("img"); imshow("img",img); waitKey(0); return 0;}
This step is simple and the result is shown as follows:
Final Positioning
In the above film, we can see that we have detected two possible rectangular positions of the license plate. Continue to make a filter to determine the real location of the license plate.
int box_selection(Mat& mat1){ int width_1, height_1; int width = mat1.rows; int height = mat1.cols; int i, j; IplImage pI_1 = mat1; CvScalar s; int find_blue = 0; int blueToWhite = 0; int sum =0; for(i=0; i<width; i++){ find_blue = 0; blueToWhite = 0; for(j=0; j
Because the license plate number is blue-white, it will appear seven times in turn at the same time. So in box_selection, after the Blue Circle, the number of jumps to white is at least five times, indicating that the position of the rectangle is the box with the license plate selected. To exclude other rectangles, and then display a new image of the fixed license plate position, and draw a yellow box at the original license plate position. The final result is as follows:
Note:
The accuracy of this method is not too high. The following situations may occur:
The code is downloaded as follows: http://download.csdn.net/detail/u011630458/8431445