首頁 > 軟體

opencv實現車牌識別

2022-07-30 14:01:10

本文範例為大家分享了opencv實現車牌識別的具體程式碼,供大家參考,具體內容如下

(1)提取車牌位置,將車牌從圖中分割出來;
(2)車牌字元的分割;
(3)通過模版匹配識別字元;
(4)將結果繪製在圖片上顯示出來。

import cv2
from matplotlib import pyplot as plt
import os
import numpy as np


# plt顯示彩色圖片
def plt_show0(img):
    # cv2與plt的影象通道不同:cv2為[b,g,r];plt為[r, g, b]
    b, g, r = cv2.split(img)
    img = cv2.merge([r, g, b])
    plt.imshow(img)
    plt.show()
    
# plt顯示灰度圖片
def plt_show(img):
    plt.imshow(img, cmap='gray')
    
    plt.show()
# 影象去噪灰度處理
def gray_guss(image):
    image = cv2.GaussianBlur(image, (3, 3), 0)
    gray_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    return gray_image
# 讀取待檢測圖片
origin_image = cv2.imread('img。png')

# 複製一張圖片,在複製圖上進行影象操作,保留原圖
image = origin_image.copy()

# 影象去噪灰度處理
gray_image = gray_guss(image)
# x方向上的邊緣檢測(增強邊緣資訊)
Sobel_x = cv2.Sobel(gray_image, cv2.CV_16S, 1, 0)
absX = cv2.convertScaleAbs(Sobel_x)
image = absX
# 影象閾值化操作——獲得二值化圖
ret, image = cv2.threshold(image, 0, 255, cv2.THRESH_OTSU)
# 顯示灰度影象
plt_show(image)
# 形態學(從影象中提取對錶達和描繪區域形狀有意義的影象分量)——閉操作
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10))
image = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernelX,iterations = 1)
# 顯示灰度影象
plt_show(image)

# 腐蝕(erode)和膨脹(dilate)
kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1))
kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 20))

#x方向進行閉操作(抑制暗細節)
image = cv2.dilate(image, kernelX)
image = cv2.erode(image, kernelX)

#y方向的開操作
image = cv2.erode(image, kernelY)
image = cv2.dilate(image, kernelY)
# 中值濾波(去噪)
image = cv2.medianBlur(image, 21)
# 顯示灰度影象
plt_show(image)
# 獲得輪廓
contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for item in contours:
    rect = cv2.boundingRect(item)
    x = rect[0]
    y = rect[1]
    weight = rect[2]
    height = rect[3]
  
    # 根據輪廓的形狀特點,確定車牌的輪廓位置並擷取影象
    if (weight > (height * 3.5)) and (weight < (height * 4)):
        image = origin_image[y:y + height, x:x + weight]
        plt_show0(image)


#車牌字元分割
# 影象去噪灰度處理
gray_image = gray_guss(image)

# 影象閾值化操作——獲得二值化圖
ret, image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_OTSU)
plt_show(image)

#膨脹操作,使「蘇」字膨脹為一個近似的整體,為分割做準備
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
image = cv2.dilate(image, kernel)
plt_show(image)


contours, hierarchy = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
words = []
word_images = []
for item in contours:
    word = []
    rect = cv2.boundingRect(item)
    x = rect[0]
    y = rect[1]
    weight = rect[2]
    height = rect[3]
    word.append(x)
    word.append(y)
    word.append(weight)
    word.append(height)
    words.append(word)
words = sorted(words,key=lambda s:s[0],reverse=False)
i = 0
for word in words:
    if (word[3] > (word[2] * 1.5)) and (word[3] < (word[2] * 3.5)) and (word[2] > 25):
        i = i+1
        splite_image = image[word[1]:word[1] + word[3], word[0]:word[0] + word[2]]
        word_images.append(splite_image)
        print(i)
print(words)

for i,j in enumerate(word_images):
    plt.subplot(1,7,i+1)
    plt.imshow(word_images[i],cmap='gray')
plt.show()

#模版匹配
# 準備模板(template[0-9]為數位模板;)
template = ['0','1','2','3','4','5','6','7','8','9',
            'A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z',
            '藏','川','鄂','甘','贛','貴','桂','黑','滬','吉','冀','津','晉','京','遼','魯','蒙','閩','寧',
            '青','瓊','陝','蘇','皖','湘','新','渝','豫','粵','雲','浙']

# 讀取一個資料夾下的所有圖片,輸入引數是檔名,返回模板檔案地址列表
def read_directory(directory_name):
    referImg_list = []
    for filename in os.listdir(directory_name):
        referImg_list.append(directory_name + "/" + filename)
    return referImg_list
# 獲得中文模板列表(只匹配車牌的第一個字元)
def get_chinese_words_list():
    chinese_words_list = []
    for i in range(34,64):
        #將模板存放在字典中
        c_word = read_directory('./refer1/'+ template[i])
        chinese_words_list.append(c_word)
    return chinese_words_list
chinese_words_list = get_chinese_words_list()

# 獲得英文模板列表(只匹配車牌的第二個字元)
def get_eng_words_list():
    eng_words_list = []
    for i in range(10,34):
        e_word = read_directory('./refer1/'+ template[i])
        eng_words_list.append(e_word)
    return eng_words_list
eng_words_list = get_eng_words_list()
# 獲得英文和數位模板列表(匹配車牌後面的字元)
def get_eng_num_words_list():
    eng_num_words_list = []
    for i in range(0,34):
        word = read_directory('./refer1/'+ template[i])
        eng_num_words_list.append(word)
    return eng_num_words_list
eng_num_words_list = get_eng_num_words_list()
# 讀取一個模板地址與圖片進行匹配,返回得分
def template_score(template,image):
template_img=cv2.imdecode(np.fromfile(template,dtype=np.uint8),1)
    template_img = cv2.cvtColor(template_img, cv2.COLOR_RGB2GRAY)
    #模板影象閾值化處理——獲得黑白圖
    ret, template_img = cv2.threshold(template_img, 0, 255, cv2.THRESH_OTSU)

    image_ = image.copy()

    height, width = image_.shape
    template_img = cv2.resize(template_img, (width, height))
    result = cv2.matchTemplate(image_, template_img, cv2.TM_CCOEFF)
    return result[0][0]
# 對分割得到的字元逐一匹配
def template_matching(word_images):
    results = []
    for index,word_image in enumerate(word_images):
        if index==0:
            best_score = []
            for chinese_words in chinese_words_list:
                score = []
                for chinese_word in chinese_words:
                    result = template_score(chinese_word,word_image)
                    score.append(result)
                best_score.append(max(score))
            i = best_score.index(max(best_score))
            # print(template[34+i])
            r = template[34+i]
            results.append(r)
            continue
        if index==1:
            best_score = []
            for eng_word_list in eng_words_list:
                score = []
                for eng_word in eng_word_list:
                    result = template_score(eng_word,word_image)
                    score.append(result)
                best_score.append(max(score))
            i = best_score.index(max(best_score))
            # print(template[10+i])
            r = template[10+i]
            results.append(r)
            continue
        else:
            best_score = []
            for eng_num_word_list in eng_num_words_list:
                score = []
                for eng_num_word in eng_num_word_list:
                    result = template_score(eng_num_word,word_image)
                    score.append(result)
                best_score.append(max(score))
            i = best_score.index(max(best_score))
            # print(template[i])
            r = template[i]
            results.append(r)
            continue
    return results
word_images_ = word_images.copy()
result = template_matching(word_images_)
print(result)

print( "".join(result))
# 未完結----------------

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com