新能源车车牌识别c++

EasyPR中主要涉及到蓝色底牌与黄色底牌、白色底牌的车牌识别,随着新能源车辆的发展,目前有很多绿色底牌的车牌,因此增加绿色车牌的识别。

  EasyPR中关于车牌的识别,已经比较完善,这里主要涉及到三个地方的修改。

1.添加颜色

include/easypr/config.h

在自定义Color的枚举类中,添加 绿色,修改之后为:

enum Color { BLUE, YELLOW, WHITE, GREEN, UNKNOWN };

添加绿色识别

  在OpenCV或其他软件中,识别颜色主要通过RGB映射到HSV空间,通过判断H、S、V的相关值来判断颜色的,主要原理可以参考:OpenCV颜色识别。修改之后的部分代码如下:

src/core/core_func.cpp

 Mat colorMatch(const Mat &src, Mat &match, const Color r,
     const bool adaptive_minsv) {
                
     // if use adaptive_minsv
     // min value of s and v is adaptive to h
     const float max_sv = 255;
     const float minref_sv = 64;
                
     const float minabs_sv = 95; //95;
                
     // H range of blue 
                
     const int min_blue = 100;  // 100
     const int max_blue = 140;  // 140
                
     // H range of yellow
                
     const int min_yellow = 15;  // 15
     const int max_yellow = 40;  // 40
                
     // H range of white
                                                                                                                                                                                                     
     const int min_white = 0;   // 15
     const int max_white = 30;  // 40
                
     //Louis add,green  
     // H range of green
                
     const int min_green = 35;   // 35
     const int max_green = 80;   // 80
                
     Mat src_hsv;

	 // convert to HSV space
     cvtColor(src, src_hsv, CV_BGR2HSV);
                 
     std::vector hsvSplit;
     split(src_hsv, hsvSplit);
     equalizeHist(hsvSplit[2], hsvSplit[2]);
     merge(hsvSplit, src_hsv);
                 
     // match to find the color
                 
     int min_h = 0;
     int max_h = 0;
     switch (r) {
     case BLUE:  
       min_h = min_blue;
       max_h = max_blue;
       break;    
     case YELLOW:
       min_h = min_yellow;
       max_h = max_yellow;
       break;    
     case WHITE: 
       min_h = min_white;
       max_h = max_white;
       break;    
     //Louis add,green  
     case GREEN: 
       min_h = min_green;
       max_h = max_green;
       break;    
     default:    
       // Color::UNKNOWN
       break;    
     }           
                 
     float diff_h = float((max_h - min_h) / 2);
     float avg_h = min_h + diff_h;                                                                                                                                                                   
                 
     int channels = src_hsv.channels();
     int nRows = src_hsv.rows;
           
	 // consider multi channel image
     int nCols = src_hsv.cols * channels;
     if (src_hsv.isContinuous()) {
       nCols *= nRows;
       nRows = 1;
     }           
                 
     int i, j;   
     uchar* p;   
     float s_all = 0;
     float v_all = 0;
     float count = 0;
     for (i = 0; i < nRows; ++i) {
       p = src_hsv.ptr(i);
       for (j = 0; j < nCols; j += 3) {
         int H = int(p[j]);      // 0-180
         int S = int(p[j + 1]);  // 0-255
         int V = int(p[j + 2]);  // 0-255
                 
         s_all += S;
         v_all += V;
         count++;
                 
         bool colorMatched = false;
                 
         if (H > min_h && H < max_h) {
           float Hdiff = 0;
           if (H > avg_h)
             Hdiff = H - avg_h;
           else  
             Hdiff = avg_h - H;                                                                                                                                                                      
                 
           float Hdiff_p = float(Hdiff) / diff_h;
                 
     float min_sv = 0;
           if (true == adaptive_minsv)
             min_sv =
             minref_sv -
             minref_sv / 2 *
             (1 
             - Hdiff_p);  // inref_sv - minref_sv / 2 * (1 - Hdiff_p)
           else 
             min_sv = minabs_sv;  // add
     
           if ((S > min_sv && S < max_sv) && (V > min_sv && V < max_sv))
             colorMatched = true;
         }      
     
         if (colorMatched == true) {
           p[j] = 0;
           p[j + 1] = 0;
           p[j + 2] = 255;
         }      
         else { 
           p[j] = 0;
           p[j + 1] = 0;
           p[j + 2] = 0;
         }
       }
     }
                
     // cout << "avg_s:" << s_all / count << endl;
     // cout << "avg_v:" << v_all / count << endl;
                
     // get the final binary
                
     Mat src_grey;
     std::vector hsvSplit_done;
     split(src_hsv, hsvSplit_done);
     src_grey = hsvSplit_done[2];
                                                                                                                                                                                                     
     match = src_grey;
     
     return src_grey;
   }

其中RGB与HSV颜色识别对应的关系,可以参考:OpenCV中HSV颜色模型及颜色分量范围

增加字符限制

  以前的车牌主要是7位字符,包括省 [A-Z].[5位字符] 的方式。但新能源车牌,后面5为字符变为6位字符,因此之前的判断方法不能够获取全部车牌,最好的情况也只能获得前面的7位字符。因此需要修改为:

src/core/chars_segment.cpp

int CCharsSegment::RebuildRect(const vector& vecRect,
                               vector& outRect, int specIndex) {   
  int count = 7;//Louis changed 6->7, for green plate car
  for (size_t i = specIndex; i < vecRect.size() && count; ++i, --count) {
    outRect.push_back(vecRect[i]);                       
  }                                                      
                                                         
  return 0;                                              
}                

至此,可以识别绿色车牌。

你可能感兴趣的:(工作日志)