計算機視覺檢測車牌號
介紹
在這個技術(shù)飛速發(fā)展的時代,在尋找一輛犯罪汽車的時候,要停下路上的每一輛車并檢查其車牌是非常困難的。隨著道路欺詐的增加,警察也變得越來越聰明。他們正在使用深度學習和計算機視覺來檢測車牌并從中提取車牌號。今天,我們將建立一個這樣的項目,使用計算機視覺來檢測車牌,這有助于電子挑戰(zhàn)和安全監(jiān)控。在本博客中,我們將學習如何使用計算機視覺檢測汽車的車牌并提取其值。我們將使用計算機視覺的 OpenCV 庫來檢測汽車的車牌,使用深度學習的 pytesseract 庫來讀取圖像類型并從車牌中獲取字符和數(shù)字。最后,我們使用 Tkinter 構(gòu)建一個圖形用戶界面來顯示我們的項目。
計算機視覺的先決條件
首先,安裝庫:
pip3 install OpenCV-python
pip3 install pytesseract
什么是 OpenCV?
OpenCV 是一個巨大的開源跨平臺庫,它使計算機視覺能夠執(zhí)行自動駕駛、圖像注釋、基于無人機的作物監(jiān)測等實際應(yīng)用。它主要專注于捕獲圖像和視頻以分析重要特征,例如物體檢測、人臉檢測、情緒檢測等,在基于圖像處理的人工智能應(yīng)用中也發(fā)揮著重要作用。
在這里,我們只是使用 openCV 的一些基本特征/功能來識別輸入的汽車圖像中的車牌號。
· 輪廓:輪廓通常被視為邊界像素,因為它們只是簡單的曲線,將邊界中具有相同強度和顏色的所有連續(xù)點組合在一起。輪廓的使用在形狀分析、對象檢測和識別、運動檢測以及背景/前景圖像分割中更加清晰。為了減少輪廓檢測的任務(wù),OpenCV 為此提供了內(nèi)置的 cv2.findContours() 函數(shù)。
cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE)
我們的 cv.find contours()函數(shù)采用三個參數(shù),包括輸入圖像、輪廓檢索模式,最后是輪廓逼近方法。該函數(shù)以 Python 列表的形式生成修改后的圖像、層次結(jié)構(gòu)和輪廓。
· 形態(tài)變換:是指只對二值圖像進行的一些簡單的操作,并依賴于圖像的形狀。一些常見的形態(tài)學操作是 Opening、Closing、Erosion、Dilation。每個函數(shù)都有兩個參數(shù),包括輸入圖像和結(jié)構(gòu)元素或內(nèi)核來決定操作的性質(zhì)。OpenCV 提供了一些內(nèi)置函數(shù)來執(zhí)行這些操作:
· cv2.erode()
· cv2.dilate()
· cv2.morphologyEx()
· **高斯模糊:**高斯函數(shù)用于對輸入圖像進行模糊和平滑處理,并輸出高斯模糊圖像。它被廣泛用于減少圖像噪聲效果。OpenCV 為此提供了一個內(nèi)置函數(shù) cv2.GaussianBlur()。
· **Sobel:**此函數(shù)用于計算圖像導數(shù),這反過來有助于梯度的計算。OpenCV 為此提供了一個內(nèi)置函數(shù) cv2.Sobel()。
使用計算機視覺構(gòu)建車牌的步驟步驟
1. 導入必要的庫
import numpy as np
import cv2
from PIL import Image
import pytesseract as pytess
步驟 2. 識別不必要的輪廓
現(xiàn)在我們將專注于識別圖片中存在的一些不必要的輪廓,這些輪廓可能會被 OpenCV 錯誤識別,因為它是車牌的可能性很小。
我們將定義三個不同的函數(shù)來找到這些輪廓。
1. 首先,我們創(chuàng)建一個名為“ratioCheck”的函數(shù)來識別面積范圍和寬高比。
2. 其次,我們創(chuàng)建一個名為“isMaxWhite”的函數(shù)來識別圖像矩陣的平均值:
3. 最后,我們創(chuàng)建一個名為“ratio_and_rotation”的函數(shù)來查找輪廓的旋轉(zhuǎn):
步驟 3 清理識別的車牌
現(xiàn)在我們的任務(wù)是創(chuàng)建一個函數(shù),通過刪除所有不必要的元素來準備用于預處理的車牌,并使圖像準備好提供給 pytesseract:
def clean2_plate(plate):
gray_img = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)
_, thresh_val = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)
if cv2.waitKey(0) & 0xff == ord('q'):
pass
num_contours,hierarchy = cv2.findContours(thresh_val.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if num_contours:
conto_ar = [cv2.contourArea(c) for c in num_contours]
max_cntr_index = np.a(chǎn)rgmax(conto_ar)
max_cnt = num_contours[max_cntr_index]
max_cntArea = conto_ar[max_cntr_index]
x,y,w,h = cv2.boundingRect(max_cnt)
if not ratioCheck(max_cntArea,w,h):
return plate,None
final_img = thresh_val[y:y+h, x:x+w]
return final_img,[x,y,w,h]
else:
return plate, None
第 4 步識別數(shù)字和字符
現(xiàn)在我們的任務(wù)是以圖像的形式獲取用戶輸入。然后,我們將執(zhí)行三個討論過的 cv2 函數(shù):Gaussian Blur、Sobel 和形態(tài)學運算并識別圖像輪廓,并從每個輪廓中找到循環(huán)來識別車牌。最后,將使用 pytesseract 庫并為其提供圖像以提取數(shù)字和字符。
img = cv2.imread("testData/img1.jpg")
print("Number input image...",)
cv2.imshow("input",img)
if cv2.waitKey(0) & 0xff == ord('q'):
pass
img2 = cv2.GaussianBlur(img, (3,3), 0)
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
img2 = cv2.Sobel(img2,cv2.CV_8U,1,0,ksize=3)
_,img2 = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(17, 3))
morph_img_threshold = img2.copy()
cv2.morphologyEx(src=img2, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img_threshold)
num_contours, hierarchy= cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE)
cv2.drawContours(img2, num_contours, -1, (0,255,0), 1)
for i,cnt in enumerate(num_contours):
min_rect = cv2.minAreaRect(cnt)
if ratio_and_rotation(min_rect):
x,y,w,h = cv2.boundingRect(cnt)
plate_img = img[y:y+h,x:x+w]
print("Number identified number plate...")
cv2.imshow("num plate image",plate_img)
if cv2.waitKey(0) & 0xff == ord('q'):
pass
if(isMaxWhite(plate_img)):
clean_plate, rect = clean2_plate(plate_img)
if rect:
fg=0
x1,y1,w1,h1 = rect
x,y,w,h = x+x1,y+y1,w1,h1
# cv2.imwrite("clena.png",clean_plate)
plate_im = Image.fromarray(clean_plate)
text = tess.image_to_string(plate_im, lang='eng')
print("Number Detected Plate Text : ",text)
項目 GUI 代碼
現(xiàn)在我們將為圖形用戶界面創(chuàng)建一個名為“gui.py”的 python 文件,以創(chuàng)建一個接受圖像作為輸入并在屏幕上輸出車牌號的web表單。
import tkinter as tk #python library for GUI
from tkinter import filedialog
from tkinter import *
from PIL import ImageTk, Image
from tkinter import PhotoImage
import numpy as np
import cv2
import pytesseract as tess
def clean2_plate(plate):#to clean the identified number plate using above discussed openCV methods
gray_img = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)
_, thresh_val = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)
num_contours,hierarchy = cv2.findContours(thresh_val.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if num_contours:
conto_ar = [cv2.contourArea(c) for c in num_contours]
max_cntr_index = np.a(chǎn)rgmax(conto_ar)
max_cnt = num_contours[max_cntr_index]
max_cntArea = conto_ar[max_cntr_index]
x,y,w,h = cv2.boundingRect(max_cnt)
if not ratioCheck(max_cntArea,w,h):
return plate,None
final_img = thresh_val[y:y+h, x:x+w]
return final_img,[x,y,w,h]
else:
return plate,None
#method to identify the range of area and ratio between width and height
def ratioCheck(Ar, breatth, height):
ratio = float(breatth) / float(height)
if ratio < 1:
ratio = 1 / ratio
if (Ar 73862.5) or (ratio 6):
return False
return True
#method to identify average of image matrix:
def isMaxWhite(plate):
avg = np.mean(plate)
if(avg>=115):
return True
else:
return False
# to find the rotation of contours:
def ratio_and_rotation(rect):
(x, y), (breatth, height), rect_angle = rect
if(breatth>height):
angle = -rect_angle
else:
angle = 90 + rect_angle
if angle>15:
return False
if height == 0 or breatth == 0:
return False
Ar = height*breatth#area calculation
if not ratioCheck(Ar,breatth,height):
return False
else:
return True
top=tk.Tk()
top.geometry('900x700')#window size
top.title('Number Plate Recognition')#title of GUI
top.iconphoto(True, PhotoImage(file="/home/shikha/GUI/logo.png"))#give the path of folder where your test image is available
img = ImageTk.PhotoImage(Image.open("logo.png"))#to open your image
top.configure(background='#CDCDCD')#background color
label=Label(top,background='#CDCDCD', font=('arial',35,'bold'))#to set background,font,and size of the label
sign_image = Label(top,bd=10)
plate_image=Label(top,bd=10)
def classify(file_path):
res_text=[0]
res_img=[0]
img = cv2.imread(file_path)
img2 = cv2.GaussianBlur(img, (3,3), 0)
img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
img2 = cv2.Sobel(img2,cv2.CV_8U,1,0,ksize=3)
_,img2 = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(17, 3))
morph_img_threshold = img2.copy()
cv2.morphologyEx(src=img2, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img_threshold)
num_contours, hierarchy= cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE)
cv2.drawContours(img2, num_contours, -1, (0,255,0), 1)
for i,cnt in enumerate(num_contours):
min_rect = cv2.minAreaRect(cnt)
if ratio_and_rotation(min_rect):
x,y,w,h = cv2.boundingRect(cnt)
plate_img = img[y:y+h,x:x+w]
print("Number identified number plate...")
res_img[0]=plate_img
cv2.imwrite("result.png",plate_img)
#method to identify average of image matrix:
if(isMaxWhite(plate_img)):
clean_plate, rect = clean2_plate(plate_img)
if rect:
fg=0
x1,y1,w1,h1 = rect
x,y,w,h = x+x1,y+y1,w1,h1
plate_im = Image.fromarray(clean_plate)
text = tess.image_to_string(plate_im, lang='eng')
res_text[0]=text
if text:
break
label.configure(foreground='#011638', text=res_text[0])
uploaded=Image.open("result.png")
im=ImageTk.PhotoImage(uploaded)
plate_image.configure(image=im)
plate_image.image=im
plate_image.pack()
plate_image.place(x=560,y=320)
def show_classify_button(file_path):
classify_b=Button(top,text="Classify Image",command=lambda: classify(file_path),padx=10,pady=5)
classify_b.configure(background='#364156', foreground='white',font=('arial',15,'bold'))
classify_b.place(x=490,y=550)
def upload_image():
try:
file_path=filedialog.a(chǎn)skopenfilename()
uploaded=Image.open(file_path)
uploaded.thumbnail(((top.winfo_width()/2.25),(top.winfo_height()/2.25)))
im=ImageTk.PhotoImage(uploaded)
sign_image.configure(image=im)
sign_image.image=im
label.configure(text='')
show_classify_button(file_path)
except:
pass
upload=Button(top,text="Upload an image",command=upload_image,padx=10,pady=5)
upload.configure(background='#364156', foreground='white',font=('arial',15,'bold'))
upload.pack()
upload.place(x=210,y=550)
sign_image.pack()
sign_image.place(x=70,y=200)
label.pack()
label.place(x=500,y=220)
heading = Label(top,image=img)
heading.configure(background='#CDCDCD',foreground='#364156')
heading.pack()
top.mainloop()
計算機視覺輸出
結(jié)論在這篇博客中,我們使用計算機視覺和深度學習來創(chuàng)建一個車牌識別和牌照號碼提取系統(tǒng)。在這里,我們創(chuàng)建了一個 GUI 來上傳車輛的圖像并識別編號。我們主要關(guān)注兩個庫:OpenCV 來清理車牌, pytesseract 識別車牌數(shù)字和字符。我們還學習了 OpenCV 的一些特殊功能,即形態(tài)變換、高斯模糊和 Sobel 算子。
原文標題 : 計算機視覺檢測車牌號
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
即日-11.13立即報名>>> 【在線會議】多物理場仿真助跑新能源汽車
-
11月28日立即報名>>> 2024工程師系列—工業(yè)電子技術(shù)在線會議
-
12月19日立即報名>> 【線下會議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會
-
即日-12.26火熱報名中>> OFweek2024中國智造CIO在線峰會
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍皮書》
-
精彩回顧立即查看>> 【限時免費下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
推薦專題
-
5 夾縫中的文遠知行
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市