Детектирование автомобильных номеров на основе контурного анализа


В Интернете встречаются статьи посвященные детектированию и распознаванию автомобильных номеров. Некоторые используют машинное обучение для того, чтобы обучить компьютер детектировать номер по типу алгоритма Виолы-Джонса. Качество и скорость работы алгоритмов оставляют желать лучшего и авторы справедливо замечают, что нужно более лучшее обучение. Несмотря на то, что машинное обучение, конечно, является важной и значимой частью распознавания образов, применять его нужно с умом. Прежде всего нужно оценить, а какие признаки характеризуют объект распознавания. Понятно, что в большинстве случаев автомобильный номер характеризуется рамкой, ограничивающей номер. Поэтому первой напрашивается идея о том, что выделить контуры-кандидаты на распознавание, которые подходят по размерам.
Для этого можно написать простейшую функцию:



void FoFindBox( IplImage* img, float max_ratio, float min_ratio, int max_area, int min_area, int Min_Lenght_Fo, 
                           CvBox2D* boxes, CvRect *Rects, double* areas, int* all_boxes )
{
        const float Min_Fill_Area = 0.4f;
         CvMemStorage* storage = cvCreateMemStorage(0);

         CvSeq* contours = 0;
         cvFindContours( img, storage, &contours, sizeof(CvContour),
                    CV_RETR_LIST  , CV_CHAIN_APPROX_NONE, cvPoint(0,0) );

         int all = 0;    
         for( CvSeq* c=contours; c!=NULL; c=c->h_next)
         {
                  CvBox2D b = cvMinAreaRect2( c );                                
                  if ( b.size.height < Min_Lenght_Fo || b.size.width < Min_Lenght_Fo || 
                           (b.size.width*b.size.height) < min_area || (b.size.width*b.size.height) > max_area ) continue;                 
                  if ( fabs( cvContourArea( c ) ) / (b.size.width*b.size.height) < Min_Fill_Area ) continue;
                  float ratio = ( (b.size.width < b.size.height)?
                  (float)b.size.width /b.size.height:
                  (float)b.size.height/b.size.width);   
                  if ( ratio < min_ratio || ratio > max_ratio ) continue;
                  

                  boxes[all] = b;
                  Rects[all] = cvBoundingRect( c );
                  ratio = (float) Rects[all].height / Rects[all].width;
                  if ( ratio < min_ratio || ratio > max_ratio ) continue;
                  if ( areas != NULL) areas[all] = cvContourArea©;
                  all++;
                  if ( all >= (*all_boxes) ) {                    
                           break;
                  }
         }

         (*all_boxes) = all;

         cvReleaseMemStorage( &storage); 
}


Вызывать эту функцию в программе будем следующим образом:

IplImage* Img=cvLoadImage(buf,CV_LOAD_IMAGE_GRAYSCALE); // buf – буфер с именем файла
IplImage* Img2=cvCreateImage( cvGetSize(Img), 8, 1);    
IplImage*ImgOut=cvLoadImage(buf);
cvAdaptiveThreshold( Img, Img2, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY,15, 0 );
CvBox2D b[1000];
CvRect r[1000];
double a[1000];
int all = 1000;
FoFindBox( Img2, 0.5f, 0.15f, 25000, 500, 5, b, r, a, &all );
for(j=0;j<all;j++)
        if ( r[j].width > r[j].height )
        cvRectangle(ImgOut,cvPoint(r[j].x,r[j].y),cvPoint(r[j].x+r[j].width,r[j].y+r[j].height),        CV_RGB(255,255,0), 2);


Результат можно посмотреть на следующих картинках:







В этом случае нужно после распознавания буквы и цифр (6 в сумме) продлить границы номера.
После детектирование для каждого кандидата на номер необходимо вызвать функцию распознавания.
В целом использование этой простейшей функции позволяет детектировать 70-80% автомобильных номеров, что однако при построении действующей системы распознавания автомобильных номеров является неудовлетворительным, поэтому необходимо усложнить функцию и/или добавить другой метод детектирования номера.
Одним из явных преимуществ контурного анализа является четко выделенная граница автомобильного номера.
  • +1
  • avatar
  • Поделиться

Комментарии (14)

0
Вариант детектирования номера по линейным размерам, на мой взгляд, можно было бы объединить со способностью к светоотражению краски номеров. Так как все номера покрыты специальной краской, то можно было бы сочетая видеорегистатор с небольшим ИК-излучателем, значительно сузить круг анализа вышеуказанного алгоритма.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.