去年七月份因为学校项目需要开始接触图像处理,但那时候只是到网上找车牌识别代码,然后加入到自己的项目中,不清楚细节原理。
现在自己重新一步步实现车牌识别。
高斯模糊:
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 }
灰度化:
1 Mat Grayscale(Mat &img) { 2 Mat out; 3 cvtColor(img, out, CV_RGB2GRAY); 4 5 return out; 6 }
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 }
二值化:
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 }
闭操作:
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 }
取轮廓:
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 }
主函数:
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 }
学习自——http://www.cnblogs.com/subconscious/p/3979988.html
时间: 2024-10-12 21:45:03