car identify Location

来源:互联网 发布:科比生涯数据图 编辑:程序博客网 时间:2024/05/22 03:24
*------------------------------ - 程序介绍------------------------------*/ //版本:VS2017 + Opencv2.4.9 //描述:OpenCV学习之路——车牌识别之车牌定位 /*-----------------------------------------------------------------------*/   #include "opencv.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2\core\core.hpp" #include "vector" #include "iostream" #include "time.h"  using namespace cv; using namespace std;  Mat histeq(Mat in) {     Mat out(in.size(), in.type());     if (in.channels() == 3) {         Mat hsv;         vector<Mat> hsvSplit;         cvtColor(in, hsv, CV_BGR2HSV);         split(hsv, hsvSplit);         equalizeHist(hsvSplit[2], hsvSplit[2]);         merge(hsvSplit, hsv);         cvtColor(hsv, out, CV_HSV2BGR);     }     else if (in.channels() == 1) {         equalizeHist(in, out);     }       return out;    }    //! 对minAreaRect获得的最小外接矩形,用纵横比进行判断  bool verifySizes(RotatedRect mr)  {      float error = 0.3;      //Spain car plate size: 52x11 aspect 4,7272      //China car plate size: 440mm*140mm,aspect 3.142857      float aspect = 3.142857;      //Set a min and max area. All other patchs are discarded      int min= 1*aspect*1; // minimum area      int max= 2000*aspect*2000; // maximum area      //int min = 44 * 14 * m_verifyMin; // minimum area      //int max = 44 * 14 * m_verifyMax; // maximum area                                       //Get only patchs that match to a respect ratio.      float rmin = aspect - aspect*error;      float rmax = aspect + aspect*error;        int area = mr.size.height * mr.size.width;      float r = (float)mr.size.width / (float)mr.size.height;      if (r < 1)      {          r = (float)mr.size.height / (float)mr.size.width;      }        if ((area < min || area > max) || (r < rmin || r > rmax))      {          return false;      }      else      {          return true;      }  }    Mat Gaussian(Mat &img) {      Mat out;      GaussianBlur(img, out, Size(3, 3),          0, 0, BORDER_DEFAULT);      return out;    }    Mat Grayscale(Mat &img) {      Mat out;      cvtColor(img, out, CV_RGB2GRAY);        return out;  }    Mat Sobel(Mat &img) {      Mat out;      Mat grad_x, grad_y;    Mat abs_grad_x, abs_grad_y;    //X方向    //Sobel(img, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);    //convertScaleAbs(grad_x, abs_grad_x);    Sobel(img, img, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);    convertScaleAbs(img, out);    //Y方向    //Sobel(img, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);    //convertScaleAbs(grad_y, abs_grad_y);     //convertScaleAbs(img, out);      //合并     //addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, out);      return out; }  Mat TwoValued(Mat &img) {     Mat out;     threshold(img, out, 0, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);     //threshold(img, out, 100, 255, CV_THRESH_BINARY);      return out; }  Mat Close(Mat &img) {     Mat out;     //Mat element(5, 5, CV_8U, cv::Scalar(1));     Mat element = getStructuringElement(MORPH_RECT, Size(17, 5));     morphologyEx(img, out, cv::MORPH_CLOSE, element);      return out; }   void Contour(Mat &img, Mat &out) {     RNG rng(12345);      vector< Mat > contours(1000);     vector<Vec4i> hierarchy(1000);     findContours(img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));   vector< Mat >::iterator itc = contours.begin();   vector<RotatedRect> rects;   int t = 0;   while (itc != contours.end()) {       //Create bounding rect of object       RotatedRect mr = minAreaRect(Mat(*itc));       //large the rect for more       if (!verifySizes(mr)) {           itc = contours.erase(itc);       }       else {           ++itc;           rects.push_back(mr);       }  }      cv::Mat result;   img.copyTo(result);   for (int i = 0; i< contours.size(); i++)   {       drawContours(result, contours, i, Scalar(0, 0, 255), 2, 8, vector<Vec4i>(), 0, Point());       //drawContours(result, contours, i, Scalar(255), 2);   }   //imshow("画轮廓", out);   for (int i = 0; i < rects.size(); i++) {       circle(result, rects[i].center, 3, Scalar(0, 255, 0), -1);       float minSize = (rects[i].size.width < rects[i].size.height) ? rects[i].size.width : rects[i].size.height;       //minSize = minSize - minSize*0.5;       srand(time(NULL));       Mat mask;       mask.create(out.rows + 2, out.cols + 2, CV_8UC1);       mask = Scalar::all(0);       int loDiff = 30;       int upDiff = 30;       int connectivity = 4;       int newMaskVal = 255;       int NumSeeds = 10;       Rect ccomp;         int flags = connectivity + (newMaskVal << 8) + CV_FLOODFILL_FIXED_RANGE + CV_FLOODFILL_MASK_ONLY;          for (int j = 0; j < NumSeeds; j++) {             Point seed;             seed.x = rects[i].center.x + rand() % (int)minSize - (minSize / 2);             seed.y = rects[i].center.y + rand() % (int)minSize - (minSize / 2);             circle(result, seed, 1, Scalar(0, 255, 255), -1);             int area = floodFill(out, mask, seed, Scalar(255, 0, 0), &ccomp, Scalar(loDiff, loDiff, loDiff), Scalar(upDiff, upDiff, upDiff), flags);         }         imshow("漫水填充", mask);                  vector<Point> pointsInterest;         Mat_<uchar>::iterator itMask = mask.begin<uchar>();         Mat_<uchar>::iterator end = mask.end<uchar>();         for (; itMask != end; ++itMask)             if (*itMask == 255)                 pointsInterest.push_back(itMask.pos());          RotatedRect minRect = minAreaRect(pointsInterest);          if (verifySizes(minRect)) {             // rotated rectangle drawing                Point2f rect_points[4]; minRect.points(rect_points);             for (int j = 0; j < 4; j++)                 line(result, rect_points[j], rect_points[(j + 1) % 4], Scalar(0, 0, 255), 1, 8);              //Get rotation matrix               float r = (float)minRect.size.width / (float)minRect.size.height;             float angle = minRect.angle;             if (r < 1)                 angle = 90 + angle;             Mat rotmat = getRotationMatrix2D(minRect.center, angle, 1);              //Create and rotate image               Mat img_rotated;             warpAffine(out, img_rotated, rotmat, out.size(), CV_INTER_CUBIC);//实现旋转              //Crop image               Size rect_size = minRect.size;             if (r < 1)                 swap(rect_size.width, rect_size.height);             Mat img_crop;             getRectSubPix(img_rotated, rect_size, minRect.center, img_crop);              Mat resultResized;             resultResized.create(33, 144, CV_8UC3);             resize(img_crop, resultResized, resultResized.size(), 0, 0, INTER_CUBIC);;              ////Equalize croped image               Mat grayResult;             cvtColor(resultResized, grayResult, CV_BGR2GRAY);// CV_RGB2GRAY             blur(grayResult, grayResult, Size(3, 3));             grayResult = histeq(grayResult);              if (1) {                 stringstream ss(stringstream::in | stringstream::out);                 ss << "haha" << "_" << i << ".jpg";                 imwrite(ss.str(), grayResult);             }          }     } }   int main() {     Mat img;     Mat out;     //Mat result;      //载入图片       img = imread("test1.jpg");//, CV_LOAD_IMAGE_GRAYSCALE);     img.copyTo(out);     //imshow ("原始图", img);     img = Gaussian(img);     imshow ("高斯模糊", img);      img = Grayscale(img);     imshow("灰度化", img);      img = Sobel(img);     imshow("Sobel_X", img);      img = TwoValued(img);     imshow("二值化", img);    img = Close(img);    imshow("闭操作", img);    Contour(img, out);    waitKey(0);    cvDestroyAllWindows();}

原创粉丝点击