車牌識別(一)-車牌定位


            在對車牌識別過程中,常用的方法有:基於形狀、基於色調、基於紋理、基於文字特征等方法。首先基於形狀,在車牌中因為車牌為形狀規格的矩形,所以目的轉化為尋找矩形特征,常常是利用車牌長寬比例特征、占據圖像的比例等。基於色調,國內的車牌往往是藍底白字,可以采用圖像的色調或者飽和度特征,進入生成二值圖,定位車牌位置。基於紋理特征自己還沒有基礎到。基於文字特征往往是根據文字輪廓特征進行識別,原理是基於相鄰文字輪廓特征、比例進行定位車牌位置。

一、圖像二值化

        正如前面文章所言,首先進行獲取圖像二值化特征,本文采取了根據圖像亮度特征,提高對比度,進行可以清晰獲取文字的圖像,為下一步的文字輪廓識別打好基礎。

1.1 算法流程

        偽代碼

1、圖像轉化為HSV圖像,獲取V通道圖像

2、提高對比度

3、V圖像高斯濾波,去除噪聲

4、圖像二值化

程序源碼:

def get_colorvalue(image):
    height, width, shape = image.shape
    image_hsv = np.zeros((height,width), np.uint8)
    image_hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
    image_hue, image_saturation, image_value = cv2.split(image_hsv)    
    return image_value
    
def enhance_contrast(image):    
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    img_tophat = cv2.morphologyEx(image, cv2.MORPH_TOPHAT,kernel)
    img_blackhat = cv2.morphologyEx(image, cv2.MORPH_BLACKHAT, kernel)
    
    image_plus_tophat = cv2.add(image, img_tophat)
    image_plus_blackhat_minus_blackhat = cv2.subtract(image_plus_tophat, img_blackhat)
return image_plus_blackhat_minus_blackhat
    
def preprocess(srcimage):
    
    image_value = get_colorvalue(srcimage)    
    image_enhance = enhance_contrast(image_value)
    
    image_blur = cv2.GaussianBlur(image_enhance, (5,5), 0)
#    _, image_binary = cv2.threshold(image_blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    _, image_binary = cv2.threshold(image_blur, 100, 255, cv2.THRESH_BINARY )
    
    cv2.imwrite('image_binary.png',image_binary)
 
    return  image_binary

1.2 算法分析

在實驗中在獲取通道圖像時,發現可以利用圖像飽和度圖像進行定位。

1、通道圖像提取

image_hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
image_hue, image_saturation, image_value = cv2.split(image_hsv)

02

image_hueimage_saturationimage_value

 

 

 

 

 

 

 

上面分別為src、hue、saturation、value四副圖像,在其中saturatio中可以清晰獲取車牌相對於背景的飽和度大,則提取較value圖像則可視為灰度圖像,能保留圖像大部分圖像特征。

關於hsv的介紹可以參考這篇文章學習Opencv筆記(二)————hsv色系文章簡單介紹hsv體系內容。

2、圖像對比度增強

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
    img_tophat = cv2.morphologyEx(image, cv2.MORPH_TOPHAT,kernel)
    img_blackhat = cv2.morphologyEx(image, cv2.MORPH_BLACKHAT, kernel)
    
    
    image_plus_black = cv2.add(image, img_blackhat)
    image_plus_blackhat_minus_blackhat = cv2.subtract(image_plus_black, img_tophat)

img_tophat

img_blackhat

                             (img_tophat)                                                                               (img_blackhat)

image_plus_tophat

image_plus_blackhat_minus_blackhat                              (ima_plus_top_hat)                                                                                 (img_plus_black_top_hat)

圖像增強的目的是提高圖像的對比度,亮度地方更亮,暗的地方更暗。在形態學處理中,頂帽操作往往用來分離比鄰近點亮一些的板塊,在一幅圖像具有大幅背景而微小物品比較有規律的情況下,可以使用頂帽運算進行背景提取。黑帽運算后的效果圖突出了比原圖輪廓周圍的區域更暗的區域,這一操作也與選擇的核尺寸有關。

流程就是,加上黑帽,減去頂冒,其實通過實驗結果發現,貌似作用不大。

形態學處理詳細介紹可以參考:數字圖像處理-形態學研究對形態學各種操作和理論進行了詳細的介紹

3.二值化

在獲取單通道圖像后,進行了圖像二值化操作,其中網上有個文章推薦使用adaptiveThreshold,其實真的不好用,我也采用了ostu算法,經過試驗驗證也不是很好用,經過多次驗證,初步定閾值為80,效果比較良好。

0_1binaryimage

 

二、圖像位置初步定位

        由於車輛圖像背景比較復雜,所以應該根據車牌的特征進行初次篩選,其特征還是根據中國車牌大小、比例等關系進行篩選。

12上圖是自己找的關於車牌的標准,我們可以清晰知道寬:高 = 3.5 所以程序設置的最小比例是2,最大是5,然后就是根據圖像大小設定的面積,長寬等大小。

2.1、算法源碼

#contants for plate contour
MIN_CONTOUR_WIDTH = 80
MIN_CONTOUR_HEIGHT = 30

MIN_CONTOUR_RATIO = 1.5
MAX_CONTOUR_RATIO = 5

MIN_CONTOURL_AREA = 1500

def get_external_contours(image_thresh):
    #    Construct display images and display contours in images
    
    height, width = image_thresh.shape
    image_contour1 = np.zeros((height, width),np.uint8)
    image_contour2 = np.zeros((height, width),np.uint8) 
    
##    Custom 3*3 nuclei undergo expansion corrosion in the X direction    
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    image_dilate= cv2.dilate(image_thresh,kernel,iterations =2)
    image_erode= cv2.erode(image_dilate, kernel, iterations = 4)
    image_dilate= cv2.dilate(image_erode,kernel,iterations = 2)
#    
    _, contours, hierarchy = cv2.findContours(image_dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    contour_filter = []
    cv2.drawContours(image_contour1, contours, -1,(255, 255, 255 ),3)
        
#    choose the suite contour by the feature of special scence
    for contour in contours:
        contour_possible = PossibleContour(contour)
        if(check_external_contour(contour_possible)): 
            cv2.rectangle(image_contour2, (contour_possible.rectX, contour_possible.rectY),
                                      (contour_possible.rectX + contour_possible.rectWidth, contour_possible.rectY + contour_possible.rectHeight),255)
            contour_filter.append(contour_possible)
            
    print("the length of origin contours is %d " %len(contour_filter))
    cv2.imwrite("1_1contours.png",image_contour1)
    cv2.imwrite("1_2contours.png",image_contour2)
    return contour_filter
    
#    #According to the license plate area size, length and width ratio, the primary screening is carried out
def check_external_contour(contour):
    if (contour.area > MIN_CONTOURL_AREA and contour.rectWidth > MIN_CONTOUR_WIDTH and contour.rectHeight > MIN_CONTOUR_HEIGHT
        and contour.whratio > MIN_CONTOUR_RATIO and contour.whratio < MAX_CONTOUR_RATIO):
        return True
    else:
        return False

2 .2、算法分析

上述算法核心是利用了findcontours函數,即在圖像中尋找目標輪廓,詳細的介紹可以參考這篇文章:

OpenCV-Python教程(11、輪廓檢測):文中很詳細介紹函數參數含義及應用

在獲取輪廓中,傳入自己定義的類中,獲取根據輪廓的矩形的面積、長寬等值,方便后續計算。

第二步就是根據上述理論分析,得到的函數。 

1_1contours1_2contours

1_1contours1_2contours

        上面四副圖片分別展示了經過篩選后的結果,對contour根據限制條件進行選擇,最終選擇符合條件的候選區域,並保存在list中。

三、圖像車牌精確定位

        在中國車牌顏色為藍底白字,所以藍色數值會比較大,我們計算候選車牌區域藍色數值(均值)的最大值,確定最終的車牌區域。

3.1 算法源碼

def chack_plate_blueHue(contour_list, image_src):
    if len(contour_list) == 0:
        print('cannot find the plate contours')
        return None
    mean_list = []

#    calculate the mean of each blue image and choose the max one,get the index
    for contour in contour_list:
        image = cv2.getRectSubPix(image_src, ( contour.rectWidth, contour.rectHeight),(contour.centerX, contour.centerY))
        b , g, r = cv2.split(image)
        sum_pix = b.shape[0] * b.shape[1]
        b_mean = np.sum(np.array(b))/sum_pix
        mean_list.append(b_mean)
        
    index = np.argmax(np.array(mean_list))
    contour_final = contour_list[index]

    return contour_final

3.2 算法分析

1、遍歷輪廓數組,根據前期獲取的候選車牌區域,通過getRectSubPix獲取其圖像

2、分離圖像,獲取blue通道圖像

3、計算圖像均值,並添加到list

4、尋找list的argmax,獲取其index

5、返回list中准確的contour

3_1image_plate3_1image_plate


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM