当前位置: 首页 > news >正文

车牌识别与标注:基于百度OCR与OpenCV的实现(一)

在这里插入图片描述

车牌识别与标注:基于百度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, ImageFontdef 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 = 30font = 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_widthfont_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) // 2text_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)]  # 替换为你的坐标值# test5coords = [(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)

运行效果:
在这里插入图片描述

代码解析

  1. 图片读取与绘制平行四边形:使用cv2.imread读取图片,然后通过cv2.fillPoly函数根据车牌的四个坐标点绘制平行四边形。
  2. 计算平行四边形宽度与包围盒:通过计算两个相邻点之间的距离来估算平行四边形的宽度,并获取包围盒的坐标范围。
  3. 文本绘制与字体大小调整:使用Pillow库(PIL)绘制文本。首先根据平行四边形宽度和指定的比例调整字体大小,然后计算文本的居中位置。
  4. 文本旋转与融合:计算文本旋转角度,将文本图层旋转后与原图融合,实现文本与平行四边形的对齐。

四、实际应用与优化

实际应用场景

  1. 交通监控系统:在交通监控中,车牌识别可以用于车辆的自动识别与追踪,帮助交通管理部门更好地管理交通流量,打击交通违法行为。
  2. 智能停车场管理:通过车牌识别,停车场可以实现自动计费、车辆进出管理等功能,提高停车场的运营效率和用户体验。

优化建议

  1. 性能优化:在实际应用中,车牌识别和标注的性能至关重要。可以通过多线程或异步处理来提高处理速度,同时优化代码逻辑,减少不必要的计算。
  2. 准确性提升:虽然百度OCR提供了较高的识别准确率,但在一些复杂场景下(如车牌污损、遮挡等)仍可能出现识别错误。可以通过增加预处理步骤(如图像增强、去噪等)来提高识别的准确性。
  3. 用户体验优化:在展示结果时,可以考虑添加更多的交互功能,如车牌信息的详细展示、历史记录查询等,提升用户的使用体验。

五、总结

本文介绍了在macOS系统下,基于百度OCR和OpenCV的车牌识别与标注技术。通过调用百度OCR API获取车牌信息,并使用OpenCV在图片上绘制标注框和车牌号码,实现了一个完整的车牌识别与标注流程。整个工程使用PyCharm进行组织和开发,代码源文件位于src/main.py,资源文件如test5.jpgSTHeiti Light.ttc位于工程根目录。在实际应用中,可以根据具体需求进行优化和扩展,以满足不同的应用场景。希望本文能够为从事相关工作的开发者提供一定的参考和帮助。


以我之思,借AI之力

http://www.lryc.cn/news/575208.html

相关文章:

  • (C++)vector数组相关基础用法(C++教程)(STL库基础教程)
  • MiniMax-M1混合MoE大语言模型(本地运行和私有化搭建)
  • 数据结构 顺序表与链表
  • 深入学习入门--(一)前备知识
  • C++11原子操作:从入门到精通
  • 从数据到决策:UI前端如何利用数字孪生技术提升管理效率?
  • Webpack 构建过程详解
  • Web层注解
  • python学习笔记(深度学习)
  • FPGA基础 -- Verilog 格雷码(Gray Code)计数器设计与原理解析
  • 【网站内容安全检测】之3:获取所有外部域名访问后图像
  • ABP VNext + Ocelot API 网关:微服务统一入口与安全策略
  • Boosting:从理论到实践——集成学习中的偏差征服者
  • webman 利用tcp 做服务端 对接物联网
  • 机器学习×第十五卷:集成学习下篇——她开始构建每一轮更接近你的贴靠路径(XGBoost)
  • 基于STM32的个人健康助手的设计
  • Containerd 容器技术
  • 基于Hp感染的慢性胃炎居家管理小程序的设计与实现(消息震动)
  • LVS-DR负载均衡群集深度实践:高性能架构设计与排障指南
  • 鸿蒙OpenHarmony[Disassembler反汇编工具]ArkTS运编译工具链
  • vue3递归组件的使用
  • LVS-NAT负载均衡群集实战:原理、部署与问题排查
  • Vue计算属性与监视属性
  • 机器人 “离线觉醒” ? 摆脱人类“控制”!Google DeepMind 优化 AI 让机器人断网不断智!
  • spring项目启动sheel脚本
  • 如何打造Apache Top-Level开源时序数据库IoTDB
  • 北斗导航 | 基于CNN-LSTM-PSO算法的接收机自主完好性监测算法
  • 服务器开放端口如何设置,本地内网开通应用端口让外网访问连接步骤
  • Fisco Bcos学习 - 控制台搭建和基本使用
  • 在ASP.NET Core WebApi中使用标识框架(Identity)