計算機視覺檢測車牌號
介紹
在這個技術飛速發展的時代,在尋找一輛犯罪汽車的時候,要停下路上的每一輛車并檢查其車牌是非常困難的。隨著道路欺詐的增加,警察也變得越來越聰明。他們正在使用深度學習和計算機視覺來檢測車牌并從中提取車牌號。今天,我們將建立一個這樣的項目,使用計算機視覺來檢測車牌,這有助于電子挑戰和安全監控。在本博客中,我們將學習如何使用計算機視覺檢測汽車的車牌并提取其值。我們將使用計算機視覺的 OpenCV 庫來檢測汽車的車牌,使用深度學習的 pytesseract 庫來讀取圖像類型并從車牌中獲取字符和數字。最后,我們使用 Tkinter 構建一個圖形用戶界面來顯示我們的項目。
計算機視覺的先決條件
首先,安裝庫:
pip3 install OpenCV-python
pip3 install pytesseract
什么是 OpenCV?
OpenCV 是一個巨大的開源跨平臺庫,它使計算機視覺能夠執行自動駕駛、圖像注釋、基于無人機的作物監測等實際應用。它主要專注于捕獲圖像和視頻以分析重要特征,例如物體檢測、人臉檢測、情緒檢測等,在基于圖像處理的人工智能應用中也發揮著重要作用。
在這里,我們只是使用 openCV 的一些基本特征/功能來識別輸入的汽車圖像中的車牌號。
· 輪廓:輪廓通常被視為邊界像素,因為它們只是簡單的曲線,將邊界中具有相同強度和顏色的所有連續點組合在一起。輪廓的使用在形狀分析、對象檢測和識別、運動檢測以及背景/前景圖像分割中更加清晰。為了減少輪廓檢測的任務,OpenCV 為此提供了內置的 cv2.findContours() 函數。
cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE)
我們的 cv.find contours()函數采用三個參數,包括輸入圖像、輪廓檢索模式,最后是輪廓逼近方法。該函數以 Python 列表的形式生成修改后的圖像、層次結構和輪廓。
· 形態變換:是指只對二值圖像進行的一些簡單的操作,并依賴于圖像的形狀。一些常見的形態學操作是 Opening、Closing、Erosion、Dilation。每個函數都有兩個參數,包括輸入圖像和結構元素或內核來決定操作的性質。OpenCV 提供了一些內置函數來執行這些操作:
· cv2.erode()
· cv2.dilate()
· cv2.morphologyEx()
· **高斯模糊:**高斯函數用于對輸入圖像進行模糊和平滑處理,并輸出高斯模糊圖像。它被廣泛用于減少圖像噪聲效果。OpenCV 為此提供了一個內置函數 cv2.GaussianBlur()。
· **Sobel:**此函數用于計算圖像導數,這反過來有助于梯度的計算。OpenCV 為此提供了一個內置函數 cv2.Sobel()。
使用計算機視覺構建車牌的步驟步驟
1. 導入必要的庫
import numpy as np
import cv2
from PIL import Image
import pytesseract as pytess
步驟 2. 識別不必要的輪廓
現在我們將專注于識別圖片中存在的一些不必要的輪廓,這些輪廓可能會被 OpenCV 錯誤識別,因為它是車牌的可能性很小。
我們將定義三個不同的函數來找到這些輪廓。
1. 首先,我們創建一個名為“ratioCheck”的函數來識別面積范圍和寬高比。

2. 其次,我們創建一個名為“isMaxWhite”的函數來識別圖像矩陣的平均值:

3. 最后,我們創建一個名為“ratio_and_rotation”的函數來查找輪廓的旋轉:

步驟 3 清理識別的車牌
現在我們的任務是創建一個函數,通過刪除所有不必要的元素來準備用于預處理的車牌,并使圖像準備好提供給 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.argmax(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 步識別數字和字符
現在我們的任務是以圖像的形式獲取用戶輸入。然后,我們將執行三個討論過的 cv2 函數:Gaussian Blur、Sobel 和形態學運算并識別圖像輪廓,并從每個輪廓中找到循環來識別車牌。最后,將使用 pytesseract 庫并為其提供圖像以提取數字和字符。
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 代碼
現在我們將為圖形用戶界面創建一個名為“gui.py”的 python 文件,以創建一個接受圖像作為輸入并在屏幕上輸出車牌號的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.argmax(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.askopenfilename()
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()
計算機視覺輸出


結論在這篇博客中,我們使用計算機視覺和深度學習來創建一個車牌識別和牌照號碼提取系統。在這里,我們創建了一個 GUI 來上傳車輛的圖像并識別編號。我們主要關注兩個庫:OpenCV 來清理車牌, pytesseract 識別車牌數字和字符。我們還學習了 OpenCV 的一些特殊功能,即形態變換、高斯模糊和 Sobel 算子。
原文標題 : 計算機視覺檢測車牌號
請輸入評論內容...
請輸入評論/評論長度6~500個字
最新活動更多
- 1 AI狂歡遇上油價破百,全球股市還能漲多久? | 產聯看全球
- 2 OpenAI深夜王炸!ChatGPT Images 2.0實測:中文穩、細節炸,設計師慌了
- 3 6000億美元估值錨定:字節跳動的“去單一化”突圍與估值重構
- 4 Tesla AI5芯片最新進展總結
- 5 連夜測了一波DeepSeek-V4,我發現它可能只剩“審美”這個短板了
- 6 熱點丨AI“瑜亮之爭”:既生OpenClaw,何生Hermes?
- 7 AI界的殺豬盤:9秒刪庫跑路,全員被封號,還繼續扣錢!
- 8 2026,人形機器人只贏了面子
- 9 DeepSeek降價90%:價格屠夫不是身份,是戰略
- 10 AI Infra產業鏈卡在哪里了?


分享













