car identify Location

*------------------------------ - 程序介绍------------------------------*/
 //版本: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();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值