OpenCV基於顏色資訊的車牌提取

wwnnvivi發表於2020-11-13

OpenCV基於顏色資訊的車牌提取

車牌提取的方法主要有:基於紋理特徵分析法、基於數學形態學分析法、基於邊緣檢測的定位分析法、基於小波分析的定位分析法、基於彩色資訊的定位分析法,本文采用的方法是基於顏色資訊的定位分析法。
本文主要參考了以下這一篇部落格,該部落格是用C++編寫的演算法,我參考其方法用Python實現了一遍。
參考的部落格(C++編寫的演算法)
在程式碼中,我詳細地註釋了每一個步驟流程以及一些注意事項,看註釋應該比較容易理解,程式碼可以直接使用。
注意把cv2.imread()函式中的圖片路徑修改一下,原始圖片我放在了部落格的最後。

#基於顏色資訊的車牌提取
#識別普通民用小型車,車牌號是藍底白字,正常光照下藍色車牌的BGR大約是(138,63,23);車牌形狀是矩形,長寬比是3:1
import cv2
import numpy as np

#讀取車輛原始影像
car_original = cv2.imread('C:\\Users\\Administrator\\Desktop\\car.jpg')
rows,cols,td = car_original.shape  #影像的行/高、列/寬、通道數
#print(rows,cols,td)  #輸出影像的大小,方便對影像的尺寸有一個瞭解
cv2.imshow('car_original',car_original)  #顯示原始影像
#基於顏色資訊進行二值化
#正常光照下藍色車牌的BGR大約是(138,63,23),由於存在一定的偏差,在二值化的時候設定一個範圍,在範圍之內
#的顏色(車牌的藍色背景)設定成白色,否則設定成黑色。
blue_goal = 138
green_goal = 63
red_goal = 23
threshold = 50  #二值化的時候,通過設定一個閾值來設定一個範圍
#注意:OpenCV中彩色影像的畫素值是BGR格式,即(blue,green,red)
for i in range(0,rows):
    for j in range(0,cols):
        B = car_original[i,j,0]
        G = car_original[i,j,1]
        R = car_original[i,j,2]
        if abs(B-blue_goal)<threshold and abs(G-green_goal)<threshold and abs(R-red_goal)<threshold:
            car_original[i,j,0] = 255
            car_original[i,j,1] = 255
            car_original[i,j,2] = 255
        else:
            car_original[i,j,0] = 0
            car_original[i,j,1] = 0
            car_original[i,j,2] = 0
cv2.imshow('car_binarization',car_original)  #顯示基於顏色資訊二值化之後的影像
#接下來進行形態學處理
#先膨脹再腐蝕
kernel = np.ones((3,3),np.int8)
dilation = cv2.dilate(car_original,kernel,iterations=1)  #膨脹一次
dilation = cv2.dilate(dilation,kernel,iterations=1)  #再膨脹一次
dilation = cv2.dilate(dilation,kernel,iterations=1)  #再膨脹一次
cv2.imshow('car_dilation',dilation)  #膨脹三次之後,可以看出車牌矩形區域內全部是白色
#再腐蝕三次
erosion = cv2.erode(dilation,kernel,iterations=1)
erosion = cv2.erode(erosion,kernel,iterations=1)
erosion = cv2.erode(erosion,kernel,iterations=1)
cv2.imshow('car_erosion',erosion)  #形態學處理之後最終得到的影像
#形態學處理之後的影像還是三通道的黑白圖,通過灰度化轉換成單通道的黑白圖
car = cv2.cvtColor(erosion,cv2.COLOR_BGR2GRAY)
#查詢輪廓
contours,hierarchy = cv2.findContours(car,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
    x,y,w,h = cv2.boundingRect(c)  #輪廓的邊界矩形,x,y是矩形左上角的座標,w,h是矩形的寬度和高度
    if w>60 and h>20:  #如果當前的這個輪廓區域足夠大,它一定是車牌號矩形區域。
                        # 如果原始影像有大面積的藍色背景,例如車的顏色是藍色的,則可以設定w和h的上限值,即min<w<max and min<h<max
        x_goal = x
        y_goal = y
        w_goal = w
        h_goal = h
        goal = c
car_goal = cv2.imread('C:\\Users\\Administrator\\Desktop\\car.jpg')
cv2.rectangle(car_goal,(x_goal,y_goal),(x_goal+w_goal,y_goal+h_goal),(0,255,0),2)  #把車牌號在原始影像上標記出來
cv2.imshow('goal',car_goal)
cv2.waitKey(0)

下圖是程式碼中使用的原始圖片car.jpg
car.jpg

相關文章