opencv實現車牌識別之車牌號定位_2,opencv_2

來源:互聯網
上載者:User

opencv實現車牌識別之車牌號定位_2,opencv_2
簡介

  前一篇講解到了將用藍色篩選後的圖片,再一次灰階/二值化。現在從這裡繼續講解。

矩形檢測
  因為車牌是一個矩形。所以接著將又一次二值化之後的圖片,進行膨脹,之後在進行矩形檢測。框選出可能是車牌號的矩形地區。代碼如下:
int** car_License_box(Mat& mat1, Mat& mat2, int* number){Mat threshold_output;vector<vector<Point> > contours;vector<Vec4i> hierarchy;Point s1, s2;int width_1, height_1;int width = mat1.rows;int height = mat1.cols;int sum = 0; int morph_elem = 3;int morph_size = 3; int** a = (int**)malloc(width * sizeof(int*)); //腐蝕Mat element = getStructuringElement(MORPH_RECT, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( -1, -1));dilate(mat1, mat1, element); /// 找到輪廓findContours(mat1, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) ); /// 多邊形逼近輪廓 + 擷取矩形和圓形邊界框vector<vector<Point> > contours_poly( contours.size() );vector<Rect> boundRect( contours.size() );vector<Point2f>center( contours.size() );vector<float>radius( contours.size() ); for( int i = 0; i < contours.size(); i++ ){ approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );boundRect[i] = boundingRect( Mat(contours_poly[i]) );minEnclosingCircle( contours_poly[i], center[i], radius[i] );} /// 畫多邊形輪廓 + 包圍的矩形框 + 圓形框mat2 = Mat::zeros(mat1.size(), CV_8UC3 );for( int i = 0; i< contours.size(); i++ ){s1 = boundRect[i].tl();s2 = boundRect[i].br();height_1 = s2.x - s1.x;width_1 =  s2.y - s1.y; if((height_1 > (3 * width_1)) && (width_1 > (width / 2))){a[sum] = (int* )malloc(4 * sizeof(int));a[sum][0] = s1.x;a[sum][1] = s1.y;a[sum][2] = s2.x;a[sum][3] = s2.y;sum += 1;}}*number = sum;return a;} int main(int argc, char **argv){     .............            pic_gray(img_3, img_3);            threshold = histogram_Calculate(img_3, 3);             pic_Thresholding(img_3, threshold);             address_1 = car_License_box(img_3, img_4, &address_Number_1);             sprintf(str, "%d", i);             namedWindow(str);            imshow(str, img_3);        }       }       waitKey(0);    return 0;}
  在函數car_License_box中,img_3為傳入的源映像,然後檢測出合適矩形,將矩形左上和右下那個角點儲存在二維數組address_1中,檢測到的矩形數量儲存在address_Number_1中。  該函數的具體流程如下:1、使用dilate來進行映像的膨脹。                          2、使用opencv教程中講解過的輪廓尋找,並將檢測到的矩形角點儲存在boundRect中。                          3、根據矩形左上和右下的角點,可以計算出矩形的寬與高。車牌所在的矩形應該長至少是寬的三倍。                             同時在之前分割的圖片中,車牌的寬度至少應該是這個分割圖片的一半以上才正常。                          4、將滿足了要求的矩形角點儲存在二維數組a中,並將矩形探測計數+1,最後返回對應儲存的二維數組。



矩形分割
  上面矩形分割,已經將可能是車牌的矩形位置角點儲存在了address_1中,這裡我們根據address_1中的角點座標,將對應的矩形從原映像中複製到新映像中顯示:
void pic_cutting_1(Mat& mat1, Mat& mat2, Point s1, Point s2){    int i, j;    IplImage pI_1;    IplImage pI_2;    CvScalar s;     mat2 = cv::Mat(s2.y - s1.y, s2.x - s1.x, CV_8UC3, 1);    pI_1 = mat1;    pI_2 = mat2;     for(i = s1.y; i < s2.y; i++){        for(j=s1.x; j<s2.x; j++){            s = cvGet2D(&pI_1, i, j);            cvSet2D(&pI_2, i-s1.y, j-s1.x, s);        }    }} int main(int argc, char** argv){      .....................            address_1 = car_License_box(img_3, img_4, &address_Number_1);             for(j=0; j< address_Number_1; j++){                 DE("address_0:%d, %d, %d, %d\n", address_1[j][0], address_1[j][1], address_1[j][2], address_1[j][3]);                s1.y = address_1[j][1] + selection_1[i][0];                s1.x = address_1[j][0];                s2.y = address_1[j][1] + selection_1[i][1];                s2.x = address_1[j][2];                DE("address:%d, %d, %d, %d\n", s1.x, s1.y, s2.x, s2.y);                 pic_cutting_1(img, img_5, s1, s2);                 sprintf(str, "%d", j);                namedWindow(str);                imshow(str, img_5);            }        }    }    namedWindow("img");                                                                                                                  imshow("img",img);    waitKey(0);    return 0;}
  這一步很簡單,效果顯示如下:
                              

最後定位
  在上面的片中,我們看到現在探測出了兩個可能是車牌的矩形位置。繼續做一次篩選判斷來確定車牌真正所在的位置。
int box_selection(Mat& mat1){    int width_1, height_1;    int width = mat1.rows;    int height = mat1.cols;    int i, j;     IplImage pI_1 = mat1;     CvScalar s;    int find_blue = 0;    int blueToWhite = 0;    int sum =0;     for(i=0; i<width; i++){        find_blue = 0;        blueToWhite = 0;        for(j=0; j<height; j++){            s = cvGet2D(&pI_1, i, j);             if((s.val[0] - s.val[1] > 10) && (s.val[0] - s.val[2] > 10) && (s.val[1] < 150) && (s.val[2] < 150)){                find_blue = 1;            }               else if((s.val[1] > 150) && (s.val[2] > 150) && (s.val[0] > 150) && (find_blue == 1)){                blueToWhite += 1;                find_blue = 0;            }        }        if(blueToWhite > 5){            sum += 1;           }      }    return sum;} int main(int argc, char **argv){  ............   for(j=0; j< address_Number_1; j++){                 DE("address_0:%d, %d, %d, %d\n", address_1[j][0], address_1[j][1], address_1[j][2], address_1[j][3]);                s1.y = address_1[j][1] + selection_1[i][0];                s1.x = address_1[j][0];                s2.y = address_1[j][1] + selection_1[i][1];                s2.x = address_1[j][2];                DE("address:%d, %d, %d, %d\n", s1.x, s1.y, s2.x, s2.y);                 pic_cutting_1(img, img_5, s1, s2);                box_flag = box_selection(img_5);                DE("box_flag:%d\n", box_flag);                 if(box_flag > 5){                    rectangle(img, s1, s2, color, 2, 8, 0 );                    sprintf(str, "%d", j);                    namedWindow(str);                    imshow(str, img_5);                }            }        }    }    namedWindow("img");    imshow("img",img);    waitKey(0);    return 0;}
  因為車牌號是藍底白字,同時會交替出現7次。所以在box_selection,我們在藍色之後,跳變到白色的次數至少大於五次,表示該矩形位置是框選了車牌。來排除掉其他的矩形,最後將確定的車牌位置新映像顯示出來,同時在原映像車牌的位置畫上黃色方框。  進而最後的效果示範如下:                                

注意
  該方法的準確率並不太高。如可能出現如下情況:                                
   代碼下載如下:http://download.csdn.net/detail/u011630458/8431445

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.