opencv實現車牌識別
本文實例為大傢分享瞭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)) # 未完結----------------
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Python如何識別銀行卡卡號?
- python中opencv實現文字分割的實踐
- 使用Python+OpenCV進行卡類型及16位卡號數字的OCR功能
- OpenCV+python實現膨脹和腐蝕的示例
- opencv實現圖像校正