本文分享的项目旨在识别车牌。为了检测车牌,我们将使用 OpenCV 来识别车牌,并使用 python pytesseract 从车牌中提取字符和数字。

Python项目演练:使用深度学习自动识别车牌号「附源代码」插图

OpenCV 是一个开源机器学习库,为计算机视觉提供通用基础设施。而 Pytesseract 是一个 Tesseract-OCR 引擎,用于读取图像类型并提取图像中存在的信息。

安装 OpenCV 和 Pytesseract pip3 python 包:

pip3install opencv-pythonpip3install pytesseract复制代码

在这个 python 项目中,为了识别输入图像中的车牌,我们将使用 openCV 的以下功能:

高斯模糊:这里我们使用高斯核来平滑图像。这种技术对于去除高斯噪声非常有效。OpenCV 为这个任务提供了一个 cv2.GaussianBlur() 函数。Sobel:这里我们计算图像的导数。此功能对于许多计算机视觉任务很重要。我们使用导数计算梯度,梯度的高变化表示图像的主要变化。OpenCV 提供了一个 cv2.Sobel() 函数来计算 Sobel 算子。形态变换:这些是基于图像形状的操作,并在二值图像上执行。基本的形态学操作是侵蚀、膨胀、开运算、闭运算。 OpenCV 中提供的不同功能是:

cv2.erode() cv2.dilate() cv2.morphologyEx()

轮廓:轮廓是包含相同强度的所有连续点的曲线。这些是非常有用的对象识别工具。 OpenCV 为此功能提供了 cv2.findContours() 函数。

下载项目源代码

在继续本项目之前,请下载源代码:Automatic Number Plate Recognition(代码包见评论)

现在,让我们深入研究车牌识别代码。请按照以下步骤操作:

1. 导入: 对于这个项目,我们需要带有 openCV 和 pytesseract 的 numpy 和 pillow python 库:

importnumpy as npimportcv2 fromPILimportImageimportpytesseract as tess 复制代码

2. 现在我们将定义三个函数,以找出 openCV 可能识别但它没有可能是车牌的不必要的轮廓。

2.1. 检查面积范围和宽高比的个函数:

defratioCheck(area,width,height):ratio=float(width)/float(height)ifratio<1:ratio=1/ratioif(area<1063.62orarea>73862.5)or(ratio<3orratio>6):returnFalsereturnTrue复制代码

2.2. 检查图像矩阵平均值的第二个函数:

defisMaxWhite(plate):avg = np.mean(plate)if(avg>=115):returnTrueelse:returnFalse复制代码

2.3. 检查轮廓旋转的第三个函数:

defratio_and_rotation(rect):(x,y), (width, height), rect_angle = rectif(width>height):angle=-rect_angleelse:angle=90 + rect_angleifangle>15:returnFalseifheight == 0 or width == 0:returnFalsearea=height*widthifnot ratioCheck(area,width,height):returnFalseelse:returnTrue复制代码

3.现在我们将编写一个函数,在喂入 pytesseract 之前清理识别的车牌进行预处理:

defclean2_plate(plate):gray_img=cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)_,thresh = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)ifcv2.waitKey(0) & 0xff == ord(q):passnum_contours,hierarchy=cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)ifnum_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)ifnot ratioCheck(max_cntArea,w,h):returnplate,Nonefinal_img=thresh[y:y+h, x:x+w]returnfinal_img,[x,y,w,h]else:returnplate, None复制代码

4. 在这一步中,我们将进行图像输入。我们将执行高斯模糊、Sobel 和形态学操作。在我们找到图像中的轮廓并循环遍历每个轮廓以识别车牌之后。然后我们将清理图像轮廓并将其提供给 pytesseract 以识别数字和字符。

img=cv2.imread(“testData/sample15.jpg”)print(“Numberinput image…”,)cv2.imshow(“input”,img)ifcv2.waitKey(0) & 0xff == ord(q):passimg2=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)fori,cnt in enumerate(num_contours):min_rect=cv2.minAreaRect(cnt)ifratio_and_rotation(min_rect):x,y,w,h=cv2.boundingRect(cnt)plate_img=img[y:y+h,x:x+w]print(“Numberidentified number plate…”)cv2.imshow(“numplate image”,plate_img)ifcv2.waitKey(0) & 0xff == ord(q):passif(isMaxWhite(plate_img)):clean_plate,rect = clean2_plate(plate_img)ifrect:fg=0x1,y1,w1,h1=rectx,y,w,h=x+x1,y+y1,w1,h1cv2.imwrite(“clena.png”,clean_plate)plate_im=Image.fromarray(clean_plate)text=tess.image_to_string(plate_im, lang=eng)print(“NumberDetected Plate Text : “,text)复制代码

项目 GUI 代码

创建一个新文件 gui.py 并粘贴以下代码:

importtkinterastkfromtkinterimportfiledialogfromtkinterimport*fromPILimportImageTk, ImagefromtkinterimportPhotoImageimportnumpyasnpimportcv2importpytesseractastessdefclean2_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)ifnum_contours: contour_area = [cv2.contourArea(c)forcinnum_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)ifnotratioCheck(max_cntArea,w,h):returnplate,Nonefinal_img = thresh[y:y+h, x:x+w]returnfinal_img,[x,y,w,h]else:returnplate,NonedefratioCheck(area, width, height):ratio = float(width) / float(height)ifratio <1: ratio =1/ ratioif(area <1063.62orarea >73862.5)or(ratio <3orratio >6):returnFalsereturnTruedefisMaxWhite(plate):avg = np.mean(plate)if(avg>=115):returnTrueelse:returnFalsedefratio_and_rotation(rect):(x, y), (width, height), rect_angle = rectif(width>height): angle = -rect_angleelse: angle =90+ rect_angleifangle>15:returnFalseifheight ==0orwidth ==0:returnFalsearea = height*widthifnotratioCheck(area,width,height):returnFalseelse:returnTruetop=tk.Tk() top.geometry(900×700) 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)defclassify(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)fori,cntinenumerate(num_contours): min_rect = cv2.minAreaRect(cnt)ifratio_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)ifrect: fg=0x1,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]=textiftext:breaklabel.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)defshow_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)defupload_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:passupload=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。

应用

自动车牌识别技术的应用也越来越广泛,比如安防、交通监管、违停监测、停车场、收费站、公安布控等等。随着这项技术越来越成熟,市场上也涌现了很多基于这项技术而开发的终端应用。

Python项目演练:使用深度学习自动识别车牌号「附源代码」插图1

在人工智能技术+视频领域,TSINGSEE青犀视频基于多年视频领域的技术经验积累,也不断研发,将AI检测、智能识别技术融合到各个视频应用场景中。典型的示例如EasyCVR视频融合云服务,具有AI人脸识别、车牌识别、语音对讲、云台控制、声光告警、监控视频分析与数据汇总的能力。

作者 nasiapp

在线客服
官方客服
我们将24小时内回复。
12:01
您好,有任何疑问请与我们联系!

选择聊天工具: