車牌識別三大步驟:
1、從圖中找出車牌
2、從車牌中識別車牌號
3、通過訓練提高識別率
本次僅實現第二步,這也是核心,其他兩個屬於附屬功能,第三個可以通過GAN或Tesseract來進行訓練,這個下篇再進行介紹。
核心步驟:
圖片處理:1、將圖片灰度化;2、將灰度圖片二值化;3、校正;4、去燥;
圖像切割識別:1、圖像切割;2、圖像識別
代碼演示(註釋):
需要導入,引入庫爲:opencv-python
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
Author Alexantao By Charm
"""
import cv2
# 定義,都可根據應用進行調整
binary_threshold = 100
segmentation_spacing = 0.9 # 普通車牌值0.95,新能源車牌改爲0.9即可
# 1、讀取圖片,並做灰度處理
img = cv2.imread('img/nycar_num_test1.png')
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
cv2.imshow('gray',img_gray)
cv2.waitKey(0)
# 2、將灰度圖二值化,設定閥值爲140
img_thre = img_gray
cv2.threshold(img_gray, binary_threshold, 255, cv2.THRESH_BINARY_INV, img_thre)
cv2.imshow('threshold', img_thre)
cv2.waitKey(0)
# 3、保存黑白圖片
cv2.imwrite('img/thre_res.png',img_thre)
# 4、分割字符
white = [] # 記錄每一列的白色像素總和
black = [] # 記錄每一列的黑色像素總和
height = img_thre.shape[0]
width = img_thre.shape[1]
print(width, height)
white_max = 0 # 僅保存每列,取列中白色最多的像素總數
black_max = 0 # 僅保存每列,取列中黑色最多的像素總數
# 循環計算每一列的黑白色像素總和
for i in range(width):
w_count = 0 # 這一列白色總數
b_count = 0 # 這一列黑色總數
for j in range(height):
if img_thre[j][i] == 255:
w_count += 1
else:
b_count += 1
white_max = max(white_max, w_count)
black_max = max(black_max, b_count)
white.append(w_count)
black.append(b_count)
# False表示白底黑字;True表示黑底白字
arg = black_max > white_max
# 分割圖像,給定參數爲要分割字符的開始位
def find_end(start_):
end_ = start_ + 1
for m in range(start_+1, width - 1):
if(black[m] if arg else white[m]) > (segmentation_spacing * black_max if arg else segmentation_spacing * white_max):
end_ = m
break
return end_
n = 1
start = 1
end = 2
while n < width - 1:
n += 1
if(white[n] if arg else black[n]) > ((1 - segmentation_spacing) * white_max if arg else (1 - segmentation_spacing) * black_max):
# 上面這些判斷用來辨別是白底黑字還是黑底白字
start = n
end = find_end(start)
n = end
if end - start > 5:
print(start, end)
cj = img_thre[1:height, start:end]
cv2.imwrite('img/{0}.png'.format(n), cj) #此句是輸出每個字符,當時未輸出直接看的時候因爲刷新問題,解決好久,後來發現只是顯示刷新的問題
cv2.imshow('cutChar', cj)
cv2.waitKey(0)
圖片:
二值圖片:(白底黑字)
分割後:
一個一個字符分割顯示。