Opencv achieves character segmentation for License Plate Recognition, opencv license plate
Introduction
In the previous article, we have located the license plate number in the image, copied the license plate number into a new image, and displayed it, this chapter continues to process the captured images. The new screenshot is as follows:
Gray-scale image/binarization
First, we chose to grayscale the image, and then start with 255 times, and take the place that accounts for 5% of the total pixel as the threshold value for binarization. The Code is as follows:
#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <math.h>#include <string.h>#include <opencv/cv.h>#include <stdio.h>#include "lib/normal.h"#include "lib/cutchar.h" #define DEBUG #ifdef DEBUG#define DE(format, ...) printf(format, ## __VA_ARGS__)#else#define DE(format, ...) while(0)#endif int main(int argc, char** argv){Mat img, img_2, img_3, img_4, img_5, img_w;IplImage pI_1;IplImage pI_2;int width, reWidth=30, wWidth=20, pic_width;int height, reHeight=100, wHeight = 20;char str[2];int i = 0, j = 0, k;int threshold = 0, pic_ArrNumber, tmp;int vArr[reHeight];int **pic_Arr;CvScalar s1;float percentage = 0.0; if(argc < 2){DE("Please input argv[1]\n");return -1;}img = cv::imread(argv[1]); namedWindow(str);imshow(str, img); width = img.rows;height = img.cols; pic_gray(img, img_2);threshold = histogram_Calculate(img_2, 5);DE("threshold:%d\n",threshold); pic_Thresholding(img_2, threshold);sprintf(str, "%d", i+1);namedWindow(str);imshow(str, img_2); waitKey(0);return 0;}
First, load the intercepted license plate number image to img, then pic_gray converts it to img_2 in gray scale, then calculates the pixel threshold value threshold at 5%, and finally performs binarization on the gray scale image img_2. The result is as follows:
Upper/lower edge separation
From the image and the surrounding area, we know that the surrounding area of the license plate number is surrounded by white borders, so we need to eliminate this interference. Here we first remove the online edge interference of the border. The Code is as follows:
int detectionChange(Mat& mat1, Mat& mat2, int number){IplImage pI_1 = mat1, pI_2;CvScalar s1, s2;int width = mat1.rows;int height = mat1.cols;int sum = 0, sum_2 = 0, width_1 = 0, width_2 = 0;int i, j; for(i=0; i<width; i++){sum = 0;sum_2 = 0;for(j=0; j
The focus is on the function detectionChange. In this function, we mainly perform the determination. First, we can determine whether a continuous 255 pixels in a row is greater than a certain proportion of the width of the row, for a single character of a normal license plate, its character width must be less than 1/6 of the width of the entire license plate; then, you can determine whether the number of pixel hops in a row from 0 to 255 or from 255 to 0 is greater than a certain number. In the row where the license plate number is located, this hop is changed at least 7 times. In detectionChange, first scan img_2 from the beginning and find the line starting with the license plate number. Then, scanning from the tail begins to find the tail end of the license plate character. Finally, copy the image to img_3. The image result is shown as follows:
Character Segmentation
After the preceding steps, the characters are separated based on the vertical projection width and accumulated values of the license plate image. The Code is as follows:
void verProjection_calculate(Mat& mat1, int* vArr, int number){ IplImage pI_1 = mat1; CvScalar s1; int width = mat1.rows; int height = mat1.cols; int i, j; for(i=0; i< number; i++){ vArr[i] = 0; } for(j=0; j
In this step, first, img_3 with the upper and lower edges are eliminated, enlarged and saved to img_4 (reWidth = 30, reHeight = 100 ), then, img_4 in the enlarged image is binarization with a new threshold of 60, and verProjection_calculate is used to calculate the vertical projection data of img_4 and save it to the one-dimensional array vArr; the verProjection_cut function uses the vertical projection data vArr to separate the character width. In verProjection_cut, if the vertical projection data to a column is less than or equal to 2, this position is not a character. The printed characters split the width position and image as follows:
Subsequent Processing
After the width is split, the corresponding character image can be split and copied on img_4, and then the interference between the edge interference on both sides and the center of the license plate can be eliminated, the appropriate image of the license plate character is obtained. The Code is as follows:
float pixelPercentage(Mat& mat1){ IplImage pI_1 = mat1; CvScalar s1; int width = mat1.rows; int height = mat1.cols; int i, j; float sum = 0, allSum = 0, tmp; for(i=0; i<width; i++){ for(j=0; j
In the code, calculate the separated character width pic_width. If the width is smaller than 3, it indicates that the character is not a normal license plate character, and exclude the image. If the value is greater than 2, the separated character image is copied to img_5. Then, the pixelPercentage function is used to calculate the ratio of image 255 to the total pixel ratio in img_5. If the value is less than 0.1, the image is the point in the license plate. The image is also excluded, and then the width is determined. If the width is greater than 2 and less than 6, the image should be 1, because the vertical projection of 1 is different from other characters, there are many differences (Note: This method can easily cause the left and right sides to be detected as 1 ). Finally, img_5 characters separated by filtering are normalized to img_5 with wWidth = 20 and wHeight = 20. After 60 is binarization, they are displayed separately. The final display effect is as follows:
Effect demonstration
The effect of using this method is not good, as shown below:
In this image, 1 is not displayed because 1 has been filtered.
, The effect of the image is very poor.
Code download location: http://download.csdn.net/detail/u011630458/8440123