车牌识别与标注:基于百度OCR与OpenCV的实现
在计算机视觉领域,车牌识别是一项极具实用价值的技术,广泛应用于交通监控、智能停车场管理等领域。本文将介绍如何在macOS系统下,利用百度OCR API进行车牌识别,并结合OpenCV库在图片上绘制标注框和车牌号码,实现一个完整的车牌识别与标注流程。整个工程将使用PyCharm进行组织和开发 。
一、系统环境与工程结构
系统环境
- 操作系统:macOS
- 开发工具:PyCharm
- Python版本:Python 3.x
工程结构
project-root/
├── src/
│ └── main.py
├── test5.jpg
└── STHeiti Light.ttc
src/main.py
:包含车牌识别与标注的代码。test5.jpg
:用于测试的图片文件。STHeiti Light.ttc
:从/System/Library/Fonts/STHeiti
拷贝的中文字体文件,用于在图片上绘制中文文本。
二、百度OCR车牌识别API简介
百度OCR(Optical Character Recognition,光学字符识别)提供了强大的车牌识别功能。通过向其API发送图片数据,我们可以获取车牌号码、车牌颜色、车牌位置等信息。API返回的数据格式如下:
https://ai.baidu.com/tech/ocr_cars/plate
{
"words_result": [
{
"number": "粤A7Z0K0",
"vertexes_location": [
{
"x": 145,
"y": 482
},
{
"x": 302,
"y": 511
},
{
"x": 294,
"y": 569
},
{
"x": 137,
"y": 539
}
],
"color": "blue",
"probability": [
0.9999998808,
1,
1,
0.9999991655,
0.9999996424,
0.9999986887,
0.9999991655
]
}
],
"log_id": "1937791826711303139"
}
其中,number
字段表示识别到的车牌号码;vertexes_location
字段是一个包含四个坐标的数组,表示车牌在图片中的位置;color
字段表示车牌颜色;probability
字段是一个数组,表示每个字符识别的置信度。
三、使用OpenCV绘制车牌标注
在获取到车牌信息后,我们需要在图片上绘制标注框并显示车牌号码。这里我们使用了OpenCV库,它是一个功能强大的计算机视觉库,提供了丰富的图像处理功能。
以下是绘制车牌标注的代码实现:
import cv2
import numpy as np
import math
from PIL import Image, ImageDraw, ImageFont
def draw_parallelogram_with_text(image_path, coords, text="车牌区域", width_ratio=0.60, font_path="STHeiti Light.ttc"):
"""
在图片上绘制平行四边形并添加对齐且宽度按比例缩放的中文文本
:param image_path: 图片路径
:param coords: 平行四边形的四个坐标点,格式为[(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
:param text: 要添加的文本,默认为"车牌区域"
:param width_ratio: 文本宽度占平行四边形宽度的比例,默认为 0.6
:param font_path: 中文字体文件路径
:return: 处理后的图片
"""
# 读取图片
image = cv2.imread(image_path)
if image is None:
raise FileNotFoundError(f"无法加载图片:{image_path}")
# 绘制平行四边形
cv2.fillPoly(image, [np.array(coords)], (255, 0, 0)) # 蓝色填充
# 计算平行四边形宽度(取前两点之间的距离作为参考宽度)
p1, p2 = coords[0], coords[1]
parallelogram_width = math.hypot(p2[0] - p1[0], p2[1] - p1[1])
# 获取包围盒
x_coords = [p[0] for p in coords]
y_coords = [p[1] for p in coords]
min_x, max_x = min(x_coords), max(x_coords)
min_y, max_y = min(y_coords), max(y_coords)
# 居中位置(先估算)
pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(pil_image)
# 初始字体大小
init_font_size = 30
font = ImageFont.truetype(font_path, init_font_size)
# 【关键修改】获取文本宽度(新方法)
init_text_width = font.getlength(text)
init_text_height = font.getmetrics()[0] # 获取字体高度(ascent)
# 根据比例调整字体大小
scale = (parallelogram_width * width_ratio) / init_text_width
font_size = int(init_font_size * scale)
font = ImageFont.truetype(font_path, font_size)
# 再次获取实际文本尺寸
text_width = font.getlength(text)
text_height = font.getmetrics()[0]
# 居中计算
text_x = min_x + (max_x - min_x - text_width) // 2
text_y = min_y + (max_y - min_y - text_height) // 2
# 创建空白图像用于绘制文字
text_layer = Image.new("RGBA", pil_image.size, (0, 0, 0, 0))
draw = ImageDraw.Draw(text_layer)
draw.text((text_x, text_y), text, fill=(255, 255, 255, 255), font=font)
# 计算旋转角度
def get_angle(p1, p2):
dx = p2[0] - p1[0]
dy = p2[1] - p1[1]
return math.degrees(math.atan2(dy, dx))
angle = get_angle(coords[0], coords[1])
# 旋转文本图层
rotated_text = text_layer.rotate(-angle, center=(text_x + text_width // 2, text_y + text_height // 2), expand=0)
# 合并到原图
pil_image.paste(rotated_text, mask=rotated_text.split()[3]) # 使用 alpha 通道做透明融合
# 转回 OpenCV 格式
result_image = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
return result_image
# 示例使用
if __name__ == "__main__":
image_path = "../test5.jpg" # 替换为你的图片路径
# 示例坐标 test3
# coords = [(417, 531), (583, 519), (586, 569), (420, 581)] # 替换为你的坐标值
# test5
coords = [(145, 482), (302, 511), (294, 569), (137, 539)] # 替换为你的坐标值
result_image = draw_parallelogram_with_text(image_path, coords)
# 显示结果
cv2.imshow("Result", result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存结果图片
cv2.imwrite("result_image.jpg", result_image)
运行效果:
代码解析
- 图片读取与绘制平行四边形:使用
cv2.imread
读取图片,然后通过cv2.fillPoly
函数根据车牌的四个坐标点绘制平行四边形。 - 计算平行四边形宽度与包围盒:通过计算两个相邻点之间的距离来估算平行四边形的宽度,并获取包围盒的坐标范围。
- 文本绘制与字体大小调整:使用Pillow库(PIL)绘制文本。首先根据平行四边形宽度和指定的比例调整字体大小,然后计算文本的居中位置。
- 文本旋转与融合:计算文本旋转角度,将文本图层旋转后与原图融合,实现文本与平行四边形的对齐。
四、实际应用与优化
实际应用场景
- 交通监控系统:在交通监控中,车牌识别可以用于车辆的自动识别与追踪,帮助交通管理部门更好地管理交通流量,打击交通违法行为。
- 智能停车场管理:通过车牌识别,停车场可以实现自动计费、车辆进出管理等功能,提高停车场的运营效率和用户体验。
优化建议
- 性能优化:在实际应用中,车牌识别和标注的性能至关重要。可以通过多线程或异步处理来提高处理速度,同时优化代码逻辑,减少不必要的计算。
- 准确性提升:虽然百度OCR提供了较高的识别准确率,但在一些复杂场景下(如车牌污损、遮挡等)仍可能出现识别错误。可以通过增加预处理步骤(如图像增强、去噪等)来提高识别的准确性。
- 用户体验优化:在展示结果时,可以考虑添加更多的交互功能,如车牌信息的详细展示、历史记录查询等,提升用户的使用体验。
五、总结
本文介绍了在macOS系统下,基于百度OCR和OpenCV的车牌识别与标注技术。通过调用百度OCR API获取车牌信息,并使用OpenCV在图片上绘制标注框和车牌号码,实现了一个完整的车牌识别与标注流程。整个工程使用PyCharm进行组织和开发,代码源文件位于src/main.py
,资源文件如test5.jpg
和STHeiti Light.ttc
位于工程根目录。在实际应用中,可以根据具体需求进行优化和扩展,以满足不同的应用场景。希望本文能够为从事相关工作的开发者提供一定的参考和帮助。
以我之思,借AI之力