最近领导给布置了一个基于图片识别车牌号的工具开发任务,然后就去研究实现逻辑,自己根据opencv写了一个小demo,发现不仅速度慢而且成功率极低。然后,就找到了Hyperlpr开源项目。
排雷1:有教程说在github上下载源码:https://github.com/zeusees/HyperLPR,自己编译,结果github上已经停止维护了,然后再gitee找到了:Hyperlpr项目
排雷2:hyperlpr环境搭建比较苛刻,建议直接在requirements.txt文件中维护好版本号
实现:
我是直接pip install hyperlpr
安装的
import cv2
from hyperlpr import HyperLPR_plate_recognition
if __name__ == '__main__':
image = cv2.imread("one.jpeg")
result = HyperLPR_plate_recognition(image)
报错:
mat_ = cv2.estimateRigidTransform(org_pts, target_pts, True)
AttributeError: module 'cv2' has no attribute 'estimateRigidTransform'
修改hyperlpr.py文件,大概在231行
将
mat_ = cv2.estimateRigidTransform(org_pts, target_pts, True)
修改为
mat_,inlier = cv2.estimateAffine2D(org_pts, target_pts)
再次执行,执行成功,返回一个列表,依次是车牌号,准确率,车牌号在图片中的坐标
经过实验发现,如果图片中存在多个车牌号,只能识别图片中的一个车牌号
拜读源码发现self.detect_ssd(image)
函数返回的是一个可迭代变量,追踪进去应该可以发现点东西
和猜测一致,self.detect_ssd(image)返回的是一个列表,但是找到一个车牌就返回了,只需要将 return cropped_images
放到for循环外卖外面即可
修改前:
修改后:
验证:
import cv2
import numpy as np
from PIL import ImageFont, Image, ImageDraw
from hyperlpr import HyperLPR_plate_recognition
if __name__ == '__main__':
image = cv2.imread("two.jpeg")
result = HyperLPR_plate_recognition(image)
print(result)
# 标记车牌号
if result:
for index, item in enumerate(result):
# 车牌号
car_code = item[0]
# 可信度
conf = item[1]
# 车牌框左上角坐标
pt1 = (item[2][0], item[2][1])
# 车牌框右下角坐标
pt2 = (item[2][2], item[2][3])
# 绘制车牌框
cv2.rectangle(image, pt1=pt1, pt2=pt2, color=(255, 0, 0), thickness=3)
# 设置需要显示的字体
font_path = 'fonts/simsun.ttc'
font = ImageFont.truetype(font_path, size=40, index=1)
image = Image.fromarray(image)
draw = ImageDraw.Draw(image)
# 绘制文字信息
draw.text((pt1[0] + 30, pt1[1] - 30), car_code, font=font, fill=(0, 0, 255))
image = np.array(image)
# cv2.namedWindow('image', 0)
# cv2.imshow('image', image)
# cv2.waitKey(100000)
cv2.imwrite('d:/two.jpeg', image)