赞
踩
本文分享的项目旨在识别车牌。为了检测车牌,我们将使用 OpenCV 来识别车牌,并使用 python pytesseract 从车牌中提取字符和数字。
OpenCV 是一个开源机器学习库,为计算机视觉提供通用基础设施。而 Pytesseract 是一个 Tesseract-OCR 引擎,用于读取图像类型并提取图像中存在的信息。
- pip3 install opencv-python
- pip3 install pytesseract
- 复制代码
在这个python项目中,为了识别输入图像中的车牌,我们将使用openCV的以下功能:
cv2.erode()
cv2.dilate()
cv2.morphologyEx()
在继续本项目之前,请下载源代码:Automatic Number Plate Recognition(代码包见评论)
现在,让我们深入研究车牌识别代码。请按照以下步骤操作:
1. 导入: 对于这个项目,我们需要带有 openCV 和 pytesseract 的 numpy 和 pillow python 库:
- import numpy as np
- import cv2
- from PIL import Image
- import pytesseract as tess
- 复制代码
2. 现在我们将定义三个函数,以找出 openCV 可能识别但它没有可能是车牌的不必要的轮廓。
2.1. 检查面积范围和宽高比的第一个函数:
- def ratioCheck(area, width, height):
- ratio = float(width) / float(height)
- if ratio < 1:
- ratio = 1 / ratio
- if (area < 1063.62 or area > 73862.5) or (ratio < 3 or ratio > 6):
- return False
- return True
- 复制代码
2.2. 检查图像矩阵平均值的第二个函数:
- def isMaxWhite(plate):
- avg = np.mean(plate)
- if(avg>=115):
- return True
- else:
- return False
- 复制代码
2.3. 检查轮廓旋转的第三个函数:
- def ratio_and_rotation(rect):
- (x, y), (width, height), rect_angle = rect
-
- if(width>height):
- angle = -rect_angle
- else:
- angle = 90 + rect_angle
-
- if angle>15:
- return False
-
- if height == 0 or width == 0:
- return False
-
- area = height*width
- if not ratioCheck(area,width,height):
- return False
- else:
- return True
- 复制代码
3.现在我们将编写一个函数,在喂入 pytesseract 之前清理识别的车牌进行预处理:
- def clean2_plate(plate):
- gray_img = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)
-
- _, thresh = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)
- if cv2.waitKey(0) & 0xff == ord('q'):
- pass
- num_contours,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
-
- if num_contours:
- contour_area = [cv2.contourArea(c) for c in num_contours]
- max_cntr_index = np.argmax(contour_area)
-
- max_cnt = num_contours[max_cntr_index]
- max_cntArea = contour_area[max_cntr_index]
- x,y,w,h = cv2.boundingRect(max_cnt)
-
- if not ratioCheck(max_cntArea,w,h):
- return plate,None
-
- final_img = thresh[y:y+h, x:x+w]
- return final_img,[x,y,w,h]
-
- else:
- return plate, None
- 复制代码
4. 在这一步中,我们将进行图像输入。我们将执行高斯模糊、Sobel 和形态学操作。在我们找到图像中的轮廓并循环遍历每个轮廓以识别车牌之后。然后我们将清理图像轮廓并将其提供给 pytesseract 以识别数字和字符。
- img = cv2.imread("testData/sample15.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.py 并粘贴以下代码:
- import tkinter as tk
- 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):
- gray_img = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)
-
- _, thresh = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)
- num_contours,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
-
- if num_contours:
- contour_area = [cv2.contourArea(c) for c in num_contours]
- max_cntr_index = np.argmax(contour_area)
-
- max_cnt = num_contours[max_cntr_index]
- max_cntArea = contour_area[max_cntr_index]
- x,y,w,h = cv2.boundingRect(max_cnt)
-
- if not ratioCheck(max_cntArea,w,h):
- return plate,None
-
- final_img = thresh[y:y+h, x:x+w]
- return final_img,[x,y,w,h]
-
- else:
- return plate,None
-
- def ratioCheck(area, width, height):
- ratio = float(width) / float(height)
- if ratio < 1:
- ratio = 1 / ratio
- if (area < 1063.62 or area > 73862.5) or (ratio < 3 or ratio > 6):
- return False
- return True
-
- def isMaxWhite(plate):
- avg = np.mean(plate)
- if(avg>=115):
- return True
- else:
- return False
-
- def ratio_and_rotation(rect):
- (x, y), (width, height), rect_angle = rect
-
- if(width>height):
- angle = -rect_angle
- else:
- angle = 90 + rect_angle
-
- if angle>15:
- return False
-
- if height == 0 or width == 0:
- return False
-
- area = height*width
- if not ratioCheck(area,width,height):
- return False
- else:
- return True
-
- top=tk.Tk()
- top.geometry('900x700')
- top.title('Number Plate Recognition')
- top.iconphoto(True, PhotoImage(file="/home/shivam/Dataflair/Keras Projects_CIFAR/GUI/logo.png"))
- img = ImageTk.PhotoImage(Image.open("logo.png"))
- top.configure(background='#CDCDCD')
- label=Label(top,background='#CDCDCD', font=('arial',35,'bold'))
- # label.grid(row=0,column=1)
- 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)
- 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()
- 复制代码
在本文中,我们开发了一个深度学习项目来识别车牌。我们讨论了 openCV 的一些重要特性,如高斯模糊、Sobel 算子、形态变换。 该应用可以从图像中检测车牌文本。为了识别车牌数字和字符,我们使用了 pytesseract。
自动车牌识别技术的应用也越来越广泛,比如安防、交通监管、违停监测、停车场、收费站、公安布控等等。随着这项技术越来越成熟,市场上也涌现了很多基于这项技术而开发的终端应用。
在人工智能技术+视频领域,TSINGSEE青犀视频基于多年视频领域的技术经验积累,也不断研发,将AI检测、智能识别技术融合到各个视频应用场景中。典型的示例如EasyCVR视频融合云服务,具有AI人脸识别、车牌识别、语音对讲、云台控制、声光告警、监控视频分析与数据汇总的能力。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。