• 车牌号识别(低级版)


    1. import cv2
    2. from matplotlib import pyplot as plt
    3. import os
    4. import numpy as np
    5. from paddleocr import PaddleOCR, draw_ocr
    6. from PIL import Image, ImageDraw, ImageFont
    7. # 利用paddelOCR进行文字扫描,并输出结果
    8. def text_scan(img_path):
    9. ocr = PaddleOCR(use_angle_cls=True, use_gpu=False)
    10. # img_path = r'test image/license_plate1.jpg'
    11. result = ocr.ocr(img_path, cls=True)
    12. for line in result:
    13. # print(line)
    14. return result
    15. # 在图片中写入将车牌信息
    16. def infor_write(img, rect, result):
    17. text = result[0][0][1][0]
    18. cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中颜色的hex码的储存顺序不同
    19. pilimg = Image.fromarray(cv2img)
    20. # PIL图片上打印汉字
    21. draw = ImageDraw.Draw(pilimg) # 图片上打印
    22. font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8") # 参数1:字体文件路径,参数2:字体大小
    23. draw.text((rect[2], rect[1]), str(text), (0, 255, 0), font=font) # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
    24. # PIL图片转cv2 图片
    25. cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
    26. return cv2charimg
    27. def plt_show0(img):
    28. #cv2与plt的图像通道不同:cv2为[b,g,r];plt为[r,g,b]
    29. b,g,r=cv2.split(img)
    30. img=cv2.merge([r,g,b])
    31. plt.imshow(img)
    32. plt.show()
    33. #plt显示灰度图片
    34. def plt_show(img):
    35. plt.imshow(img,camp='gray')
    36. plt.show()
    37. # 图像去噪灰度处理
    38. def gray_guss(img):
    39. img = cv2.GaussianBlur(img, (1, 1), 0)
    40. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    41. return gray
    42. # 图像尺寸变换
    43. def img_resize(img):
    44. a = 400 * img.shape[0] / img.shape[1]
    45. a = int(a)
    46. img = cv2.resize(img, (400, a))
    47. return img
    48. # Sobel检测,x方向上的边缘检测(增强边缘信息)
    49. def Sobel_detec(img):
    50. Sobel_x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
    51. absX = cv2.convertScaleAbs(Sobel_x)
    52. return absX
    53. # 寻找某区域最大外接矩形框4点坐标
    54. def find_retangle(contour):
    55. y, x = [], []
    56. for p in contour:
    57. y.append(p[0][0])
    58. x.append(p[0][1])
    59. return [min(y), min(x), max(y), max(x)]
    60. # 寻找并定位车牌轮廓位置
    61. def locate_license(img):
    62. blocks = []
    63. contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    64. for c in contours:
    65. x, y, w, h = cv2.boundingRect(c)
    66. r = find_retangle(c)
    67. a = (r[2] - r[0]) * (r[3] - r[1])
    68. s = (r[2] - r[0]) / (r[3] - r[1])
    69. print(w)
    70. if (w > (h * 3)) and (w < (h * 5)):
    71. blocks.append([r, a, s])
    72. # blocks.append([r, a, s])
    73. blocks = sorted(blocks, key=lambda b: b[1])[-3:]
    74. maxweight, maxindex = 0, -1
    75. for i in range(len(blocks)):
    76. b = oriimg[blocks[i][0][1]:blocks[i][0][3], blocks[i][0][0]:blocks[i][0][2]]
    77. hsv = cv2.cvtColor(b, cv2.COLOR_BGR2HSV)
    78. lower = np.array([70, 150, 50])
    79. upper = np.array([120, 255, 255])
    80. mask = cv2.inRange(hsv, lower, upper)
    81. w1 = 0
    82. for m in mask:
    83. w1 += m / 255
    84. w2 = 0
    85. for w in w1:
    86. w2 += w
    87. if w2 > maxweight:
    88. maxindex = i
    89. maxweight = w2
    90. print('blocks是', blocks[maxindex])
    91. print('blocks0是',blocks[maxindex][0])
    92. return blocks[maxindex][0]
    93. # 图像预处理+车牌轮廓位置检测
    94. def fine_lisecenpts(img):
    95. # 图像去噪灰度处理
    96. guss = gray_guss(img)
    97. # Sobel检测,增强边缘信息
    98. sobel = Sobel_detec(guss)
    99. # 图像阈值化操作——获得二值化图
    100. ret, threshold = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU)
    101. # # 对二值化图像进行边缘检测(可选,通过边缘检测后,最终进行形态学运算得到的轮廓面积更大)
    102. # threshold=cv2.Canny(threshold,threshold.shape[0],threshold.shape[1])
    103. # 形态学运算(从图像中提取对表达和描绘区域形状有意义的图像分量)——闭操作
    104. kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10))
    105. closing = cv2.morphologyEx(threshold, cv2.MORPH_CLOSE, kernelX, iterations=1)
    106. # 腐蚀(erode)和膨胀(dilate)
    107. kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1))
    108. kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 20))
    109. # x方向上进行闭操作(抑制暗细节)
    110. img = cv2.dilate(closing, kernelX)
    111. img = cv2.erode(img, kernelX)
    112. # y方向上进行开操作
    113. img = cv2.erode(img, kernelY)
    114. img = cv2.dilate(img, kernelY)
    115. # 进行中值滤波去噪
    116. Blur = cv2.medianBlur(img, 15)
    117. # 寻找轮廓
    118. rect = locate_license(Blur)
    119. print('rect是',rect)
    120. return rect, Blur
    121. # 车牌字符识别
    122. def seg_char(rect_list, img):
    123. img = oriimg[rect_list[1]:rect_list[3], rect_list[0]:rect_list[2]]
    124. # 图像去噪灰度处理
    125. gray = gray_guss(img)
    126. # 图像阈值化操作-获得二值化图(可选)
    127. # ret,charimage=cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    128. # 图像进行闭运算
    129. k1 = np.ones((1, 1), np.uint8)
    130. close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, k1)
    131. cv2.imshow('close', close)
    132. cv2.imwrite(r"E:\ultralytics-20240216\21\img2\6.jpg", close)
    133. cv2.waitKey()
    134. res = text_scan(r"E:\ultralytics-20240216\21\img2\6.jpg")
    135. return res
    136. def put_chinese_text(img, text, left_top):
    137. # 转换 cv2 img 为 PIL Image
    138. img_PIL = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    139. draw = ImageDraw.Draw(img_PIL)
    140. font = ImageFont.truetype('simhei.ttf', 30, encoding="utf-8")
    141. # 黄色文字
    142. fillColor = (255,255,0)
    143. position = left_top
    144. draw.text(position, text, font=font, fill=fillColor)
    145. # 转换回 OpenCV 格式
    146. img_out = cv2.cvtColor(np.asarray(img_PIL),cv2.COLOR_RGB2BGR)
    147. return img_out
    148. # 主函数区
    149. if __name__ == '__main__':
    150. img = cv2.imread(r"E:\ultralytics-20240216\21\img2\5.jpg")
    151. # 改变图像尺寸
    152. img = img_resize(img)
    153. oriimg = img.copy()
    154. # 寻找到车牌外轮廓矩形坐标
    155. print(1)
    156. rect, img = fine_lisecenpts(img)
    157. # 利用车牌轮廓坐标划分ROI区域用于字符识别,利用OCR识别车牌字符并返回字符串内容
    158. result = seg_char(rect, oriimg)
    159. print(result)
    160. print(rect)
    161. # 循环读取车牌字符串并写入到图片中
    162. text = result[0][0][1][0]
    163. # 获取文本所在的矩形位置
    164. left_top = tuple(rect[0:2])
    165. right_bottom = tuple(rect[2:4])
    166. # 在原始图像上绘制矩形(黄色框)
    167. cv2.rectangle(oriimg, left_top, right_bottom, (0, 255, 255), 2)
    168. # 在矩形旁边写入文本
    169. # 注意你可能需要根据实际情况调整文本的位置
    170. text_position = (right_bottom[0] + 1, right_bottom[1])
    171. oriimg = put_chinese_text(oriimg, text, text_position)
    172. # cv2.putText(oriimg, text, text_position, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)
    173. cv2.imshow("Image with text", oriimg)
    174. cv2.waitKey(0)
    175. cv2.destroyAllWindows()

  • 相关阅读:
    计算机视觉系列-AlexNet论文复现学习笔记(一)
    Django源码学习——配置文件解析
    【计算机组成原理之存储系统】超级详细
    Grafana安装配置
    【python debug】python常见编译问题解决方法_1
    Calendar日历类
    算法训练Day39 | LeetCode62. 不同路径;LeetCode63.不同路径II
    初识结构体
    OFD文件打开教程
    List知识总结
  • 原文地址:https://blog.csdn.net/qq_53821866/article/details/139656159