目錄
一、基礎理論
1、思想
2、大致程序
二、詳細程序
1、首先需要模板庫
2、得到模板
3、原圖限定大小
4、模板匹配
5、匹配所有子檔案夾,保存最佳得分(最匹配項)
三、大致程序(細分類,節省時間)
1、漢字匹配
2、英文字符匹配
3、數字/英文匹配
4、顯示
模板匹配總代碼
參考資料
一、基礎理論
1、思想
把提取到的每一張字符,和模板庫中的所有字符進行對比,
2、大致程序
先拿到模板庫,把模板和待匹配的影像大小限制一致,匹配每一張子模板圖,匹配每張模板圖匹配后都會有一個得分,得分最高的最相近,再把每個子檔案夾最高得分對比,用index找到最高的那個子檔案夾下標,得到模板,
二、詳細程序
1、首先需要模板庫
模板庫下載鏈接1:(推薦)
https://download.csdn.net/download/great_yzl/21974008
模板庫下載鏈接2:(不推薦)
http://www.zengqiang.club/blog/34
一個大檔案夾
下包含很多子檔案夾:

每一個子檔案夾內包含該字符的一系列模板(為了更精確,犧牲了不少時間):

2、得到模板
# 路徑
path = 'Template/' + List[i] + '/' + filename
# 1、得到模板
template = cv.imdecode(np.fromfile(path, dtype=np.uint8), 1) #彩(類似imread)
gray = cv.cvtColor(template, cv.COLOR_RGB2GRAY) #灰
ret, template = cv.threshold(gray, 0, 255, cv.THRESH_OTSU) #二值
cv.imshow('template', template)
cv.waitKey(0)

3、原圖限定大小
# 2、原圖限定大小(和模板相似)
h, w = template.shape
image = cv.resize(image, (w, h))
cv.imshow('image_', image)
cv.waitKey(0)

4、模板匹配
按照名稱串列的方式,遍歷模板庫的所有子檔案夾、子檔案夾內的所有子圖,
# 3、模板匹配,得到得分(匹配度越高,得分越大)
result = cv.matchTemplate(image, template, cv.TM_CCOEFF)
score.append(result[0][0]) #得分(每張模板圖)


5、匹配所有子檔案夾,保存最佳得分(最匹配項)
匹配所有子檔案夾的子圖:
# 模板匹配,得到得分(匹配度越高,得分越大)
result = cv.matchTemplate(image, template, cv.TM_CCOEFF)
score.append(result[0][0]) #得分(每張模板圖)

每個檔案夾的最佳得分:
# 一個檔案夾的最高得分(得分越高,匹配度越高)
best_score.append(max(score))
# 根據所有檔案夾的最佳得分確定下標
index = best_score.index(max(best_score))+34

三、大致程序(細分類,節省時間)
由于第一個必定是漢字,第二個必定是英文字符,后面的必定是英文字符/數字,我們在那里只需要做相應的判斷即可,節約了很多時間,
1、漢字匹配
# (1) 漢字(首個位置只能是漢字(省))(為了節約時間)
if con == 0:
# 遍歷34——65檔案夾(漢字)
for i in range(34,65):
# 單個圖片的得分
score = []
ForderPath = 'Template/' + List[i]
# 遍歷單檔案夾(每一個檔案匹配)
for filename in os.listdir(ForderPath):
# 路徑
path = 'Template/' + List[i] + '/' + filename
# 1、得到模板
template = cv.imdecode(np.fromfile(path, dtype=np.uint8), 1) #彩(類似imread)
gray = cv.cvtColor(template, cv.COLOR_RGB2GRAY) #灰
ret, template = cv.threshold(gray, 0, 255, cv.THRESH_OTSU) #二值
# 2、原圖限定大小(和模板相似)
h, w = template.shape
image = cv.resize(image, (w, h))
cv.imshow('image_', image)
cv.waitKey(0)
# 3、模板匹配,得到得分(匹配度越高,得分越大)
result = cv.matchTemplate(image, template, cv.TM_CCOEFF)
score.append(result[0][0]) #得分(每張模板圖)
# 4、保存子檔案夾的最高得分(得分越高,匹配度越高)
best_score.append(max(score))
# 5、根據所有檔案夾的最佳得分確定下標
index = best_score.index(max(best_score))+34

2、英文字符匹配
# (2) 字母(第二個位置只能為字母)
elif con == 1:
# 遍歷10~34檔案夾(字母檔案夾)
for i in range(10,34):
# 單個圖片的得分
score = []
ForderPath = 'Template/' + List[i]
# 遍歷單檔案夾(每一個檔案匹配)
for filename in os.listdir(ForderPath):
# 路徑
path = 'Template/' + List[i] + '/' + filename
# 模板
template = cv.imdecode(np.fromfile(path, dtype=np.uint8), 1) #彩(類似imread)
gray = cv.cvtColor(template, cv.COLOR_RGB2GRAY) #灰
ret, template = cv.threshold(gray, 0, 255, cv.THRESH_OTSU) #二值
h, w = template.shape
image = cv.resize(image, (w, h))
# 模板匹配,得到得分(匹配度越高,得分越大)
result = cv.matchTemplate(image, template, cv.TM_CCOEFF)
score.append(result[0][0]) #得分(每張模板圖)
# 一個檔案夾的最高得分(得分越高,匹配度越高)
best_score.append(max(score))
# 根據所有檔案夾的最佳得分確定下標
index = best_score.index(max(best_score)) + 10

3、數字/英文匹配
# (3) 數字+字母
else:
# 遍歷0~34檔案夾(數字+字母)
for i in range(34):
# 單個圖片的得分
score = []
ForderPath = 'Template/' + List[i]
# 遍歷單檔案夾(每一個檔案匹配)
for filename in os.listdir(ForderPath):
# 路徑
path = 'Template/' + List[i] + '/' + filename
# 模板
template = cv.imdecode(np.fromfile(path, dtype=np.uint8), 1) #彩(類似imread)
gray = cv.cvtColor(template, cv.COLOR_RGB2GRAY) #灰
ret, template = cv.threshold(gray, 0, 255, cv.THRESH_OTSU) #二值
h, w = template.shape
image = cv.resize(image, (w, h))
# 模板匹配,得到得分(匹配度越高,得分越大)
result = cv.matchTemplate(image, template, cv.TM_CCOEFF)
score.append(result[0][0]) #得分(每張模板圖)
# 一個檔案夾的最高得分(得分越高,匹配度越高)
best_score.append(max(score))
# 根據所有檔案夾的最佳得分確定下標
index = best_score.index(max(best_score))

4、顯示
在切割字符函式的尾部,所有字符切割完、立刻進行模板匹配,同一張車牌所有字符切割完畢后,進行顯示,
# 顯示識別結果(影像)
Show_Result_Image()
# 顯示識別結果(影像)
def Show_Result_Image():
p = image_rect[0], image_rect[1]
w, h = image_rect[2] , image_rect[3]
# 框出車牌
cv.rectangle(img, (p[0],p[1]), (p[0]+w, p[1]+h), (0,0,255), 2)
# 輸出字符(中文)
result = Text(img, str(final_result), p, (255,0,0), 16)
cv.imshow('result-%d'%count, result)
# cv.waitKey(0)

模板匹配總代碼
# 顯示文字(中文)(用的PIL,RGB正常顯示,即和opencv的RGB相反)
def Text(image, text, p, color, size):
# cv2讀取圖片
# BGR轉RGB:cv2和PIL中顏色的hex碼的儲存順序不同
cv2_image = cv.cvtColor(image, cv.COLOR_RGB2BGR)
pil_image = Image.fromarray(cv2_image)
# PIL圖片上列印漢字
draw = ImageDraw.Draw(pil_image) # 圖片上列印
font = ImageFont.truetype("./simhei.ttf", size, encoding="utf-8") # 引數1:字體檔案路徑,引數2:字體大小
draw.text((p[0]-60, p[1]-20), text, color, font=font)
# PIL圖片轉cv2 圖片
cv2_result = cv.cvtColor(np.array(pil_image), cv.COLOR_RGB2BGR)
# cv2.imshow("圖片", cv2_result) # 漢字視窗標題顯示亂碼
# cv.imshow("photo", cv2_result) # 輸出漢字
return cv2_result
# 顯示識別結果(文字)
def Show_Result_Words(index):
print(List[index])
final_result.append(List[index])
print(final_result)
# 顯示識別結果(影像)
def Show_Result_Image():
p = image_rect[0], image_rect[1]
w, h = image_rect[2] , image_rect[3]
# 框出車牌
cv.rectangle(img, (p[0],p[1]), (p[0]+w, p[1]+h), (0,0,255), 2)
# 輸出字符(中文)
result = Text(img, str(final_result), p, (255,0,0), 16)
cv.imshow('result-%d'%count, result)
# cv.waitKey(0)
# 三、模板匹配
# 原圖和模板進行對比,越匹配,得分越大
def Template_Match(image):
# 單檔案夾內的最佳得分
best_score = []
# 遍歷所有檔案夾(每一個檔案夾匹配)
# (1) 漢字(首個位置只能是漢字(省))(為了節約時間)
if con == 0:
# 遍歷34——65檔案夾(漢字)
for i in range(34,65):
# 單個圖片的得分
score = []
ForderPath = 'Template/' + List[i]
# 遍歷單檔案夾(每一個檔案匹配)
for filename in os.listdir(ForderPath):
# 路徑
path = 'Template/' + List[i] + '/' + filename
# 1、得到模板
template = cv.imdecode(np.fromfile(path, dtype=np.uint8), 1) #彩(類似imread)
gray = cv.cvtColor(template, cv.COLOR_RGB2GRAY) #灰
ret, template = cv.threshold(gray, 0, 255, cv.THRESH_OTSU) #二值
# 2、原圖限定大小(和模板相似)
h, w = template.shape
image = cv.resize(image, (w, h))
# 3、模板匹配,得到得分(匹配度越高,得分越大)
result = cv.matchTemplate(image, template, cv.TM_CCOEFF)
score.append(result[0][0]) #得分(每張模板圖)
# 4、保存子檔案夾的最高得分(得分越高,匹配度越高)
best_score.append(max(score))
# 5、根據所有檔案夾的最佳得分確定下標
index = best_score.index(max(best_score))+34
# (2) 字母(第二個位置只能為字母)
elif con == 1:
# 遍歷10~34檔案夾(字母檔案夾)
for i in range(10,34):
# 單個圖片的得分
score = []
ForderPath = 'Template/' + List[i]
# 遍歷單檔案夾(每一個檔案匹配)
for filename in os.listdir(ForderPath):
# 路徑
path = 'Template/' + List[i] + '/' + filename
# 模板
template = cv.imdecode(np.fromfile(path, dtype=np.uint8), 1) #彩(類似imread)
gray = cv.cvtColor(template, cv.COLOR_RGB2GRAY) #灰
ret, template = cv.threshold(gray, 0, 255, cv.THRESH_OTSU) #二值
h, w = template.shape
image = cv.resize(image, (w, h))
# 模板匹配,得到得分(匹配度越高,得分越大)
result = cv.matchTemplate(image, template, cv.TM_CCOEFF)
score.append(result[0][0]) #得分(每張模板圖)
# 一個檔案夾的最高得分(得分越高,匹配度越高)
best_score.append(max(score))
# 根據所有檔案夾的最佳得分確定下標
index = best_score.index(max(best_score)) + 10
# (3) 數字+字母
else:
# 遍歷0~34檔案夾(數字+字母)
for i in range(34):
# 單個圖片的得分
score = []
ForderPath = 'Template/' + List[i]
# 遍歷單檔案夾(每一個檔案匹配)
for filename in os.listdir(ForderPath):
# 路徑
path = 'Template/' + List[i] + '/' + filename
# 模板
template = cv.imdecode(np.fromfile(path, dtype=np.uint8), 1) #彩(類似imread)
gray = cv.cvtColor(template, cv.COLOR_RGB2GRAY) #灰
ret, template = cv.threshold(gray, 0, 255, cv.THRESH_OTSU) #二值
h, w = template.shape
image = cv.resize(image, (w, h))
# 模板匹配,得到得分(匹配度越高,得分越大)
result = cv.matchTemplate(image, template, cv.TM_CCOEFF)
score.append(result[0][0]) #得分(每張模板圖)
# 一個檔案夾的最高得分(得分越高,匹配度越高)
best_score.append(max(score))
# 根據所有檔案夾的最佳得分確定下標
index = best_score.index(max(best_score))
# 顯示結果(文字)(每識別一個顯示一次)
Show_Result_Words(index)
總的來講,為了追求較高的精度,匹配時間較長, 一張車牌約20秒,這里的模板匹配不算非常的精確,并且耗時嚴重,已經逐漸被淘汰了,這里只是作為學習用途,沒有太高的實際應用價值,(后期進軍深度學習/機器學習,可能會對這些進行優化),有什么好的建議大家可以提出來,共同進步,謝謝~
參考資料
https://www.bilibili.com/video/BV1yg4y187kU?p=3
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/298197.html
標籤:其他
