当前位置:   article > 正文

Python项目演练:使用深度学习自动识别车牌号【附源代码】_pydesigner做车牌识别

pydesigner做车牌识别

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

 

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

安装 OpenCV 和 Pytesseract pip3 python 包:

  1. pip3 install opencv-python
  2. pip3 install pytesseract
  3. 复制代码

在这个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 库:

  1. import numpy as np
  2. import cv2
  3. from PIL import Image
  4. import pytesseract as tess
  5. 复制代码

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

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

  1. def ratioCheck(area, width, height):
  2. ratio = float(width) / float(height)
  3. if ratio < 1:
  4. ratio = 1 / ratio
  5. if (area < 1063.62 or area > 73862.5) or (ratio < 3 or ratio > 6):
  6. return False
  7. return True
  8. 复制代码

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

  1. def isMaxWhite(plate):
  2. avg = np.mean(plate)
  3. if(avg>=115):
  4. return True
  5. else:
  6. return False
  7. 复制代码

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

  1. def ratio_and_rotation(rect):
  2. (x, y), (width, height), rect_angle = rect
  3. if(width>height):
  4. angle = -rect_angle
  5. else:
  6. angle = 90 + rect_angle
  7. if angle>15:
  8. return False
  9. if height == 0 or width == 0:
  10. return False
  11. area = height*width
  12. if not ratioCheck(area,width,height):
  13. return False
  14. else:
  15. return True
  16. 复制代码

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

  1. def clean2_plate(plate):
  2. gray_img = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)
  3. _, thresh = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)
  4. if cv2.waitKey(0) & 0xff == ord('q'):
  5. pass
  6. num_contours,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  7. if num_contours:
  8. contour_area = [cv2.contourArea(c) for c in num_contours]
  9. max_cntr_index = np.argmax(contour_area)
  10. max_cnt = num_contours[max_cntr_index]
  11. max_cntArea = contour_area[max_cntr_index]
  12. x,y,w,h = cv2.boundingRect(max_cnt)
  13. if not ratioCheck(max_cntArea,w,h):
  14. return plate,None
  15. final_img = thresh[y:y+h, x:x+w]
  16. return final_img,[x,y,w,h]
  17. else:
  18. return plate, None
  19. 复制代码

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

  1. img = cv2.imread("testData/sample15.jpg")
  2. print("Number input image...",)
  3. cv2.imshow("input",img)
  4. if cv2.waitKey(0) & 0xff == ord('q'):
  5. pass
  6. img2 = cv2.GaussianBlur(img, (3,3), 0)
  7. img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
  8. img2 = cv2.Sobel(img2,cv2.CV_8U,1,0,ksize=3)
  9. _,img2 = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
  10. element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(17, 3))
  11. morph_img_threshold = img2.copy()
  12. cv2.morphologyEx(src=img2, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img_threshold)
  13. num_contours, hierarchy= cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE)
  14. cv2.drawContours(img2, num_contours, -1, (0,255,0), 1)
  15. for i,cnt in enumerate(num_contours):
  16. min_rect = cv2.minAreaRect(cnt)
  17. if ratio_and_rotation(min_rect):
  18. x,y,w,h = cv2.boundingRect(cnt)
  19. plate_img = img[y:y+h,x:x+w]
  20. print("Number identified number plate...")
  21. cv2.imshow("num plate image",plate_img)
  22. if cv2.waitKey(0) & 0xff == ord('q'):
  23. pass
  24. if(isMaxWhite(plate_img)):
  25. clean_plate, rect = clean2_plate(plate_img)
  26. if rect:
  27. fg=0
  28. x1,y1,w1,h1 = rect
  29. x,y,w,h = x+x1,y+y1,w1,h1
  30. # cv2.imwrite("clena.png",clean_plate)
  31. plate_im = Image.fromarray(clean_plate)
  32. text = tess.image_to_string(plate_im, lang='eng')
  33. print("Number Detected Plate Text : ",text)
  34. 复制代码

项目 GUI 代码

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

  1. import tkinter as tk
  2. from tkinter import filedialog
  3. from tkinter import *
  4. from PIL import ImageTk, Image
  5. from tkinter import PhotoImage
  6. import numpy as np
  7. import cv2
  8. import pytesseract as tess
  9. def clean2_plate(plate):
  10. gray_img = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)
  11. _, thresh = cv2.threshold(gray_img, 110, 255, cv2.THRESH_BINARY)
  12. num_contours,hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
  13. if num_contours:
  14. contour_area = [cv2.contourArea(c) for c in num_contours]
  15. max_cntr_index = np.argmax(contour_area)
  16. max_cnt = num_contours[max_cntr_index]
  17. max_cntArea = contour_area[max_cntr_index]
  18. x,y,w,h = cv2.boundingRect(max_cnt)
  19. if not ratioCheck(max_cntArea,w,h):
  20. return plate,None
  21. final_img = thresh[y:y+h, x:x+w]
  22. return final_img,[x,y,w,h]
  23. else:
  24. return plate,None
  25. def ratioCheck(area, width, height):
  26. ratio = float(width) / float(height)
  27. if ratio < 1:
  28. ratio = 1 / ratio
  29. if (area < 1063.62 or area > 73862.5) or (ratio < 3 or ratio > 6):
  30. return False
  31. return True
  32. def isMaxWhite(plate):
  33. avg = np.mean(plate)
  34. if(avg>=115):
  35. return True
  36. else:
  37. return False
  38. def ratio_and_rotation(rect):
  39. (x, y), (width, height), rect_angle = rect
  40. if(width>height):
  41. angle = -rect_angle
  42. else:
  43. angle = 90 + rect_angle
  44. if angle>15:
  45. return False
  46. if height == 0 or width == 0:
  47. return False
  48. area = height*width
  49. if not ratioCheck(area,width,height):
  50. return False
  51. else:
  52. return True
  53. top=tk.Tk()
  54. top.geometry('900x700')
  55. top.title('Number Plate Recognition')
  56. top.iconphoto(True, PhotoImage(file="/home/shivam/Dataflair/Keras Projects_CIFAR/GUI/logo.png"))
  57. img = ImageTk.PhotoImage(Image.open("logo.png"))
  58. top.configure(background='#CDCDCD')
  59. label=Label(top,background='#CDCDCD', font=('arial',35,'bold'))
  60. # label.grid(row=0,column=1)
  61. sign_image = Label(top,bd=10)
  62. plate_image=Label(top,bd=10)
  63. def classify(file_path):
  64. res_text=[0]
  65. res_img=[0]
  66. img = cv2.imread(file_path)
  67. img2 = cv2.GaussianBlur(img, (3,3), 0)
  68. img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
  69. img2 = cv2.Sobel(img2,cv2.CV_8U,1,0,ksize=3)
  70. _,img2 = cv2.threshold(img2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
  71. element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(17, 3))
  72. morph_img_threshold = img2.copy()
  73. cv2.morphologyEx(src=img2, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img_threshold)
  74. num_contours, hierarchy= cv2.findContours(morph_img_threshold,mode=cv2.RETR_EXTERNAL,method=cv2.CHAIN_APPROX_NONE)
  75. cv2.drawContours(img2, num_contours, -1, (0,255,0), 1)
  76. for i,cnt in enumerate(num_contours):
  77. min_rect = cv2.minAreaRect(cnt)
  78. if ratio_and_rotation(min_rect):
  79. x,y,w,h = cv2.boundingRect(cnt)
  80. plate_img = img[y:y+h,x:x+w]
  81. print("Number identified number plate...")
  82. res_img[0]=plate_img
  83. cv2.imwrite("result.png",plate_img)
  84. if(isMaxWhite(plate_img)):
  85. clean_plate, rect = clean2_plate(plate_img)
  86. if rect:
  87. fg=0
  88. x1,y1,w1,h1 = rect
  89. x,y,w,h = x+x1,y+y1,w1,h1
  90. plate_im = Image.fromarray(clean_plate)
  91. text = tess.image_to_string(plate_im, lang='eng')
  92. res_text[0]=text
  93. if text:
  94. break
  95. label.configure(foreground='#011638', text=res_text[0])
  96. uploaded=Image.open("result.png")
  97. im=ImageTk.PhotoImage(uploaded)
  98. plate_image.configure(image=im)
  99. plate_image.image=im
  100. plate_image.pack()
  101. plate_image.place(x=560,y=320)
  102. def show_classify_button(file_path):
  103. classify_b=Button(top,text="Classify Image",command=lambda: classify(file_path),padx=10,pady=5)
  104. classify_b.configure(background='#364156', foreground='white',font=('arial',15,'bold'))
  105. classify_b.place(x=490,y=550)
  106. def upload_image():
  107. try:
  108. file_path=filedialog.askopenfilename()
  109. uploaded=Image.open(file_path)
  110. uploaded.thumbnail(((top.winfo_width()/2.25),(top.winfo_height()/2.25)))
  111. im=ImageTk.PhotoImage(uploaded)
  112. sign_image.configure(image=im)
  113. sign_image.image=im
  114. label.configure(text='')
  115. show_classify_button(file_path)
  116. except:
  117. pass
  118. upload=Button(top,text="Upload an image",command=upload_image,padx=10,pady=5)
  119. upload.configure(background='#364156', foreground='white',font=('arial',15,'bold'))
  120. upload.pack()
  121. upload.place(x=210,y=550)
  122. sign_image.pack()
  123. sign_image.place(x=70,y=200)
  124. label.pack()
  125. label.place(x=500,y=220)
  126. heading = Label(top,image=img)
  127. heading.configure(background='#CDCDCD',foreground='#364156')
  128. heading.pack()
  129. top.mainloop()
  130. 复制代码

概括

在本文中,我们开发了一个深度学习项目来识别车牌。我们讨论了 openCV 的一些重要特性,如高斯模糊、Sobel 算子、形态变换。 该应用可以从图像中检测车牌文本。为了识别车牌数字和字符,我们使用了 pytesseract。

应用

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/85256
推荐阅读
相关标签
  

闽ICP备14008679号