首页 > 代码库 > OpenCV学习之路——车牌识别之车牌定位

OpenCV学习之路——车牌识别之车牌定位

去年七月份因为学校项目需要开始接触图像处理,但那时候只是到网上找车牌识别代码,然后加入到自己的项目中,不清楚细节原理。

现在自己重新一步步实现车牌识别。

 

高斯模糊:

技术分享
1 Mat Gaussian(Mat &img) {
2     Mat out;
3     GaussianBlur(img, out, Size(3, 3),
4         0, 0, BORDER_DEFAULT);
5     return out;
6 
7 }
View Code

灰度化:

技术分享
1 Mat Grayscale(Mat &img) {
2     Mat out;
3     cvtColor(img, out, CV_RGB2GRAY);
4 
5     return out;
6 }
View Code

Sobel算子(X方向):

技术分享
 1 Mat Sobel(Mat &img) {
 2     Mat out;
 3     Mat grad_x, grad_y;
 4     Mat abs_grad_x, abs_grad_y;
 5 
 6     //X方向
 7     //Sobel(img, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
 8     //convertScaleAbs(grad_x, abs_grad_x);
 9     Sobel(img, img, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
10     convertScaleAbs(img, out);
11 
12     //Y方向
13     //Sobel(img, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
14     //convertScaleAbs(grad_y, abs_grad_y);
15     //convertScaleAbs(img, out);
16 
17     //合并
18     //addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, out);
19 
20     return out;
21 }
View Code

二值化:

技术分享
1 Mat TwoValued(Mat &img) {
2     Mat out;
3     threshold(img, out, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
4     //threshold(img, out, 100, 255, CV_THRESH_BINARY);
5 
6     return out;
7 }
View Code

闭操作:

技术分享
1 Mat Close(Mat &img) {
2     Mat out;
3     //Mat element(5, 5, CV_8U, cv::Scalar(1));
4     Mat element = getStructuringElement(MORPH_RECT, Size(17, 5));
5     morphologyEx(img, out, cv::MORPH_CLOSE, element);
6 
7     return out;
8 }
View Code

取轮廓:

技术分享
  1 void Contour(Mat &img, Mat &out) {
  2     RNG rng(12345);
  3 
  4     vector< Mat > contours(1000);
  5     vector<Vec4i> hierarchy(1000);
  6     findContours(img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
  7 
  8 
  9     vector< Mat >::iterator itc = contours.begin();
 10     vector<RotatedRect> rects;
 11     int t = 0;
 12     while (itc != contours.end()) {
 13         //Create bounding rect of object
 14         RotatedRect mr = minAreaRect(Mat(*itc));
 15         //large the rect for more
 16         if (!verifySizes(mr)) {
 17             itc = contours.erase(itc);
 18         }
 19         else {
 20             ++itc;
 21             rects.push_back(mr);
 22         }
 23    }
 24     
 25     cv::Mat result;
 26     img.copyTo(result);
 27     for (int i = 0; i< contours.size(); i++)
 28     {
 29         drawContours(result, contours, i, Scalar(0, 0, 255), 2, 8, vector<Vec4i>(), 0, Point());
 30         //drawContours(result, contours, i, Scalar(255), 2);
 31     }
 32 
 33     //imshow("MASK11", result);
 34 
 35     for (int i = 0; i < rects.size(); i++) {
 36         circle(result, rects[i].center, 3, Scalar(0, 255, 0), -1);
 37 
 38         float minSize = (rects[i].size.width < rects[i].size.height) ? rects[i].size.width : rects[i].size.height;
 39         //minSize = minSize - minSize*0.5;
 40 
 41         srand(time(NULL));
 42         Mat mask;
 43         mask.create(out.rows + 2, out.cols + 2, CV_8UC1);
 44         mask = Scalar::all(0);
 45         int loDiff = 30;
 46         int upDiff = 30;
 47         int connectivity = 4;
 48         int newMaskVal = 255;
 49         int NumSeeds = 10;
 50         Rect ccomp;
 51         int flags = connectivity + (newMaskVal << 8) + CV_FLOODFILL_FIXED_RANGE + CV_FLOODFILL_MASK_ONLY;
 52 
 53         for (int j = 0; j < NumSeeds; j++) {
 54             Point seed;
 55             seed.x = rects[i].center.x + rand() % (int)minSize - (minSize / 2);
 56             seed.y = rects[i].center.y + rand() % (int)minSize - (minSize / 2);
 57             circle(result, seed, 1, Scalar(0, 255, 255), -1);
 58             int area = floodFill(out, mask, seed, Scalar(255, 0, 0), &ccomp, Scalar(loDiff, loDiff, loDiff), Scalar(upDiff, upDiff, upDiff), flags);
 59         }
 60 
 61         //imshow("MASK", mask);
 62         
 63         vector<Point> pointsInterest;
 64         Mat_<uchar>::iterator itMask = mask.begin<uchar>();
 65         Mat_<uchar>::iterator end = mask.end<uchar>();
 66         for (; itMask != end; ++itMask)
 67             if (*itMask == 255)
 68                 pointsInterest.push_back(itMask.pos());
 69 
 70         RotatedRect minRect = minAreaRect(pointsInterest);
 71 
 72         if (verifySizes(minRect)) {
 73             // rotated rectangle drawing   
 74             Point2f rect_points[4]; minRect.points(rect_points);
 75             for (int j = 0; j < 4; j++)
 76                 line(result, rect_points[j], rect_points[(j + 1) % 4], Scalar(0, 0, 255), 1, 8);
 77 
 78             //Get rotation matrix  
 79             float r = (float)minRect.size.width / (float)minRect.size.height;
 80             float angle = minRect.angle;
 81             if (r < 1)
 82                 angle = 90 + angle;
 83             Mat rotmat = getRotationMatrix2D(minRect.center, angle, 1);
 84 
 85             //Create and rotate image  
 86             Mat img_rotated;
 87             warpAffine(out, img_rotated, rotmat, out.size(), CV_INTER_CUBIC);//实现旋转
 88 
 89             //Crop image  
 90             Size rect_size = minRect.size;
 91             if (r < 1)
 92                 swap(rect_size.width, rect_size.height);
 93             Mat img_crop;
 94             getRectSubPix(img_rotated, rect_size, minRect.center, img_crop);
 95 
 96             Mat resultResized;
 97             resultResized.create(33, 144, CV_8UC3);
 98             resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC);;
 99 
100             ////Equalize croped image  
101             Mat grayResult;
102             cvtColor(resultResized, grayResult, CV_BGR2GRAY);// CV_RGB2GRAY
103             blur(grayResult, grayResult, Size(3, 3));
104             grayResult = histeq(grayResult);
105 
106             if (1) {
107                 stringstream ss(stringstream::in | stringstream::out);
108                 ss << "haha" << "_" << i << ".jpg";
109                 imwrite(ss.str(), grayResult);
110             }
111 
112         }
113     }
114 }
View Code

主函数:

技术分享
 1 int main() {
 2     Mat img;
 3     Mat out;
 4     //Mat result;
 5 
 6     //载入图片  
 7     img = imread("test1.jpg");//, CV_LOAD_IMAGE_GRAYSCALE);
 8     img.copyTo(out);
 9     //imshow ("原始图", img);
10 
11     img = Gaussian(img);
12     //imshow ("高斯模糊", img);
13 
14     img = Grayscale(img);
15     //imshow("灰度化", img);
16 
17     img = Sobel(img);
18     //imshow("Sobel_X", img);
19 
20     img = TwoValued(img);
21     //imshow("二值化", img);
22 
23     img = Close(img);
24     //imshow("闭操作", img);
25 
26     //
27     Contour(img, out);
28 
29     waitKey(0);
30     cvDestroyAllWindows();
31 }
View Code

学习自——http://www.cnblogs.com/subconscious/p/3979988.html

OpenCV学习之路——车牌识别之车牌定位