车牌定位html5,车牌识别(一)——车牌定位(附详细代码及注释)
車牌識別分三步:車牌定位,車牌字符分割,車牌字符識別。
本篇就車牌定位進行講述。車牌定位顧名思義——找出車牌的位置。如何實現,又分三步:圖像預處理,數學形態學粗定位,長寬比例精確定位。
首先,對圖像預處理:
彩色圖像轉灰度圖
高斯濾波,中值濾波
邊緣化檢測
二值化操作
#-*- coding: utf-8 -*-
import cv2
import numpy as np
def Process(img):
# 高斯平滑
gaussian = cv2.GaussianBlur(img, (3, 3), 0, 0, cv2.BORDER_DEFAULT)
#cv2.GaussianBlur(src,ksize,sigmaX[,sigmaxY[,borderType]]])高斯濾波函數
#src: 輸入圖像
#ksize: 高斯內核大小,元組類型
#sigmaX: 高斯核函數在X方向上的標準偏差
#sigmaY: 高斯核函數在Y方向上的標準偏差,如果sigmaY是0,則函數會自動將sigmaY的值設置為與sigmaX相同的值,如果sigmaX和sigmaY都是0,這兩個值將由ksize[0]和ksize[1]計算而來。建議將size、sigmaX和sigmaY都指定出來。
#borderType: 推斷圖像外部像素的某種便捷模式,有默認值cv2.BORDER_DEFAULT,如果沒有特殊需要不用更改,具體可以參考borderInterpolate()函數。
# 中值濾波
median = cv2.medianBlur(gaussian, 5)
#cv2.medianBlur(src,ksize)
#src: 輸入圖像
#ksize: 高斯內核大小,元組類型
# Sobel算子
# 梯度方向: x
sobel = cv2.Sobel(median, cv2.CV_8U, 1, 0, ksize=3)
# 利用Sobel方法可以進行sobel邊緣檢測
# img表示源圖像,即進行邊緣檢測的圖像
# 圖像深度是cv2.CV_8U、cv2.CV_16U、cv2.CV_16S、cv2.CV_32F以及cv2.CV_64F其中的某一個
# 第三和第四個參數分別是對X和Y方向的導數(即dx,dy),對于圖像來說就是差分,這里1表示對X求偏導(差分),0表示不對Y求導(差分)。其中,X還可以求2次導。
# 注意:對X求導就是檢測X方向上是否有邊緣。
# 第五個參數ksize是指核的大小。
# 這里說明一下,這個參數的前四個參數都沒有給誰賦值,而ksize則是被賦值的對象
# 實際上,這是可省略的參數,而前四個是不可省的參數。注意其中的不同點值化
ret, binary = cv2.threshold(sobel, 170, 255, cv2.THRESH_BINARY)
#灰度值小于175的點置0,灰度值大于175的點置255
#最后的參數是閾值類型,對應一個公式,一般用這個就可以
然后,數學形態學處理: 形態學處理的核心就是定義結構元素,一般情況下對二值化圖像進行的操作。
# 膨脹和腐蝕操作的核函數
element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 1))
element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 7))
#第一個參數定義結構元素,如橢圓(MORPH_ELLIPSE)、交叉形結構(MORPH_CROSS)和矩形(MORPH_RECT)
#第二個參數就是指和函數的size,9×1
# 膨脹一次,讓輪廓突出
dilation = cv2.dilate(binary, element2, iterations=1)
# 腐蝕一次,去掉細小雜點
erosion = cv2.erode(dilation, element1, iterations=1)
# 再次膨脹,讓輪廓更明顯
dilation2 = cv2.dilate(erosion, element2, iterations=3)
#存儲中間圖片
cv2.imwrite("binary.png", binary)
cv2.imwrite("dilation.png", dilation)
cv2.imwrite("erosion.png", erosion)
cv2.imwrite("dilation2.png", dilation2)
return dilation2
最后:查找輪廓,精確定位
查找篩選輪廓
車牌長寬比
顏色判斷(沒大必要)
def GetRegion(img):
regions = []
# 查找輪廓
_, contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
#三個輸入參數:輸入圖像(二值圖像),輪廓檢索方式,輪廓近似方法
#輪廓檢索方式:cv2.RETR_EXTERNAL只檢測外輪廓。cv2.RETR_LIST檢測的輪廓不建立等級關系。cv2.RETR_CCOMP建立兩個等級的輪廓,上面一層為外邊界,里面一層為內孔的邊界信息。cv2.RETR_TREE建立一個等級樹結構的輪廓
#輪廓近似方法:cv2.CHAIN_APPROX_NONE存儲所有邊界點。cv2.CHAIN_APPROX_SIMPLE壓縮垂直、水平、對角方向,只保留端點。cv2.CHAIN_APPROX_TX89_L1使用teh-Chini近似算法。cv2.CHAIN_APPROX_TC89_KCOS使用teh-Chini近似算法
#三個返回值:圖像,輪廓,輪廓的層析結構
#篩選面積小的
for contour in contours:
#計算該輪廓的面積
area = cv2.contourArea(contour)
#面積小的都篩選掉
if (area < 2000):
continue
#輪廓近似,作用很小
epslion = 1e-3 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epslion, True)
#epsilon,是從輪廓到近似輪廓的最大距離。是一個準確率參數,好的epsilon的選擇可以得到正確的輸出。True決定曲線是否閉合。
# 找到最小的矩形,該矩形可能有方向
rect = cv2.minAreaRect(contour)
# box是四個點的坐標
box = cv2.boxPoints(rect)
box = np.int0(box)
## 計算高和寬
height = abs(box[0][1] - box[2][1])
width = abs(box[0][0] - box[2][0])
#車牌正常情況下長高比在2-5之間
ratio =float(width) / float(height)
if (ratio < 5 and ratio > 2):
regions.append(box)
return regions
def detect(img):
# 灰度化
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 預處理及形態學處理,得到可以查找矩形的圖片
prc = Process(gray)
#得到車牌輪廓
regions = GetRegion(prc)
print('[INFO]:Detect %d license plates' % len(regions))
#用綠線畫出這些找到的輪廓
for box in regions:
cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
#五個輸入參數:原始圖像,輪廓,輪廓的索引(當設置為-1時,繪制所有輪廓),畫筆顏色,畫筆大小
#一個返回值:返回繪制了輪廓的圖像
cv2.imshow('Result', img)
#保存結果文件名
cv2.imwrite('result.jpg', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
#輸入的參數為圖片的路徑
img = cv2.imread('1.jpg')
detect(img)
總結
以上是生活随笔為你收集整理的车牌定位html5,车牌识别(一)——车牌定位(附详细代码及注释)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 合并两个数组并去重(ES5和ES6两种方
- 下一篇: 分布式队列编程:模型、实战