【树莓派5】车牌识别、图像分割、人体关键点识别
本文介绍了树莓派 5 结合 OpenCV 实现车牌识别、结合 YOLOv8n 模型实现图像分割、人体关键点检测的板端推理的项目设计。
项目介绍
树莓派 5 板端部署 OpenCV 软件包,结合 Haar 级联分类和 YuNet 算法实现人脸检测、结合 YOLO 算法实现物体识别。
环境搭建:OpenCV 安装、Ultralytics 软件包安装、预训练模型下载等;
车识别:采用 LPRNet 算法及 ONNX 模型实现车牌识别的板端推理;
图像分割:采用 YOLOv8 算法及模型实现图像分割;
人体关键点检测:采用 YOLOv8 算法实现人体关键点检测;
准备工作
创建虚拟环境,避免干扰系统 Python;
安装 OpenCV 和 Ultralytics 软件包,便于算法和模型调用及代码简化;
下载所需模型与预训练文件。
详见:人脸检测与物体识别 | 树莓派5 .
车牌识别
车牌识别网络(License Plate Recognition Network,LPRNet)是一种专为车牌识别设计的深度学习模型。


它采用端到端的训练方法,能够直接从原始图像中识别出车牌文本,无需进行传统的字符分割步骤。
这种设计使得 LPRNet 在处理车牌识别任务时更加高效和准确,特别是在面对复杂背景或不同国家的车牌样式时。
详见:LPRNet GitHub .
模型
下载所需模型文件;
wget https://github.com/h030162/PlateRecognition/blob/main/ocr_rec.py wget https://github.com/h030162/PlateRecognition/blob/main/license_models/dict.txt wget https://github.com/h030162/PlateRecognition/blob/main/license_models/license_ocr.onnx wget https://github.com/h030162/PlateRecognition/blob/main/license_models/y11n-pose_plate_best.onnx
将文件存放在对应路径
license_plate_recognition ├── img │ ├── yue.jpg ├── lpr_onnx.py ├── model │ ├── dict.txt │ ├── license_ocr.onnx │ └── y11n-pose_plate_best.onnx └── ocr_rec.py
参考:PlateRecognition | Github .
代码
终端执行 source ~/cv/venv/bin/activate 激活虚拟环境;
执行 touch lpr_onnx.py 新建程序文件,并添加如下代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import cv2
from ocr_rec import TextRecognizer, init_args
from PIL import Image, ImageDraw, ImageFont
from ultralytics import YOLO
import warnings
warnings.filterwarnings("ignore")
# ========== 图片路径 ==========
#IMG_FILE = "./img/yue.jpg"
args = init_args().parse_args()
IMG_FILE = args.image_path or './img/yue.jpg' # 图片路径
# 使用方法:python lpr_onnx.py --image_path ./img/jing.jpg
# =========== 复用类 ===========
class PlateRecognizer:
def __init__(self, det_model_path="./model/y11n-pose_plate_best.onnx"):
self.model_det = YOLO(det_model_path)
parser = init_args().parse_args()
self.model_ocr = TextRecognizer(parser)
def recognize(self, img):
plate_objs = []
plates = self.model_det(img, verbose=False)
for plate, conf in zip(plates[0].boxes.xyxy, plates[0].boxes.conf):
x1, y1, x2, y2 = map(int, plate.cpu())
plate_img = img[y1:y2, x1:x2]
try:
rec_res, _ = self.model_ocr([plate_img])
except Exception as E:
print(E)
continue
if len(rec_res[0]) > 0:
plate_objs.append({
'text': rec_res[0][0],
'score_text': rec_res[0][1],
'bbox': [x1, y1, x2, y2],
'score_bbox': conf.cpu().numpy().item()
})
return plate_objs
def DrawPlateNum(img, plate_num, x1, y1):
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_pil = Image.fromarray(img_rgb)
draw = ImageDraw.Draw(img_pil)
#font = ImageFont.truetype("simsun.ttc", 40) # 使用自定义字体
font = ImageFont.truetype("/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc", 40) # 系统字体
#draw.text((x1, y1 - 40), plate_num, font=font, fill=(255, 255, 0)) # 识别结果标注
# -------- 优化标签显示,增加填充背景,兼容新版 Pillow ----------------
left, top, right, bottom = draw.textbbox((0, 0), plate_num, font=font)
tw, th = right - left, bottom - top
# 蓝色填充条
draw.rectangle([(x1, y1 - th - 8), (x1 + tw, y1)], fill=(0, 0, 255)) # BGR 蓝色
# 绿色文字
draw.text((x1, y1 - th - 16), plate_num, font=font, fill=(0, 255, 0)) # BGR 绿色
return cv2.cvtColor(np.array(img_pil, dtype=np.uint8), cv2.COLOR_RGB2BGR)
# ========== 主程序 ==========
def main():
img = cv2.imread(IMG_FILE)
if img is None:
print(f"未找到图片:{IMG_FILE}")
cv2.waitKey(0)
return
recognizer = PlateRecognizer()
plates = recognizer.recognize(img)
for p in plates:
x1, y1, x2, y2 = p['bbox']
cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2)
img = DrawPlateNum(img, p['text'], x1, y1)
print(f"车牌: {p['text']} 置信度: {p['score_text']:.4f} 框置信度: {p['score_bbox']:.4f}")
cv2.imshow("LPR", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
main()保存代码。
效果
终端执行 python lpr_onnx.py --image_path ./img/jing.jpg 指令,对目标车牌进行识别
终端打印识别到的车牌号、置信度等信息


弹窗显示识别结果


更多测试效果









识别精度较高,速度较快。

图像分割
图像切割算法是计算机视觉中的核心技术,旨在将图像划分为具有相似特征的区域或对象,以便进一步分析和处理。常见的图像切割方法包括基于阈值、区域、边缘以及深度学习的算法。


模型
获取目标模型(这里使用 YOLO 预训练模型 yolov8n-seg.pt 权重文件);
wget https://github.com/ultralytics/assets/releases/download/v8.3.0/yolov8n-seg.pt
将其放置于 model 文件夹。
代码
终端执行 source ~/cv/venv/bin/activate 激活虚拟环境;
执行 touch seg_yolo.py 新建程序文件,并添加如下代码
#!/usr/bin/env python3
import cv2
from ultralytics import YOLO
model = YOLO('./model/yolov8n-seg.pt') # 实例分割模型
img = cv2.imread('./img/road.jpg')
# 推理 + 分割(返回带 mask 的 Annotator 结果)
results = model(img, imgsz=640, conf=0.25)
# 画到原图
annotated = results[0].plot() # mask + 框 + 标签
# 弹窗显示
cv2.imshow("YOLOv8-Seg", annotated)
cv2.waitKey(0)
cv2.destroyAllWindows()保存代码。
优化
通过修改蒙版透明度,可获得更清晰的图像分割效果,代码如下
import cv2
import numpy as np
from ultralytics import YOLO
model = YOLO('./model/yolov8n-seg.pt')
img = cv2.imread('./img/road.jpg')
h, w = img.shape[:2]
results = model(img, imgsz=640, conf=0.25)
# 复制原图
annotated = img.copy()
# mask 叠加
alpha = 0.6 # 填充透明度(值越小越透明)
for r in results:
for mask, cls in zip(r.masks.xy, r.boxes.cls):
color = (int(cls)*30, 255-int(cls)*30, 255)
pts = np.int32(mask)
# 填充内部
overlay = annotated.copy()
cv2.fillPoly(overlay, [pts], color=color)
annotated = cv2.addWeighted(annotated, 1-alpha, overlay, alpha, 0)
# 加粗轮廓
cv2.polylines(annotated, [pts], isClosed=True,
color=color, thickness=2, lineType=cv2.LINE_AA)
# 画框和标签
annotated = results[0].plot(img=annotated, masks=False)
cv2.namedWindow("Image Segmentation", cv2.WINDOW_NORMAL) # 自定义缩放画面
cv2.imshow("Image Segmentation", annotated)
cv2.waitKey(0)
cv2.destroyAllWindows()可实现更清晰的图像分割轮廓显示。
效果
终端执行 python seg_yolo.py 指令;
终端打印图像分割结果;
弹窗显示结果


更多效果演示






获得了较为精确的图像分割效果,且保持较快的执行速度。

人体关键点检测
人体关键点检测(Human Keypoints Detection)或人体姿态估计,是通过识别和定位人体的特定关节(如肩膀、肘部、膝盖等)来分析人体姿态和动作的技术。


该技术可在图像中检测出人体,并精确获取关键点的坐标信息,通常指定 17 到 24 个关键点。
在默认的 YOLOv8 姿势估计模型中,有17个关键点,每个关键点代表人体不同的部位。1-17 每个索引对应身体关节的映射分别为
鼻子、左眼、右眼、左耳、右耳、左肩、右肩、左手肘、右肘、左手腕、右腕、左髋、右髋、左膝、右膝、左脚踝、右脚踝。
模型
获取目标模型(这里使用 YOLO 预训练模型 yolov8n-pose.pt 权重文件);
wget https://github.com/ultralytics/assets/releases/download/v8.3.0/yolov8n-pose.pt
将其放置于 model 文件夹。
代码
终端执行 source ~/cv/venv/bin/activate 激活虚拟环境;
执行 touch pose_yolo.py 新建程序文件,并添加如下代码
#!/usr/bin/env python3
import cv2
from ultralytics import YOLO
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--image', default='./img/pos_dance.jpg', help='输入[>
args = parser.parse_args()
IMG_FILE = args.image
model = YOLO('./model/yolov8n-pose.pt') # 关键点模型
# img = cv2.imread('./img/pos_dance.jpg')
img = cv2.imread(IMG_FILE)
results = model(img, imgsz=640, conf=0.25) # 返回 Keypoints
# annotated = results[0].plot(kpt_radius=4, kpt_line=True) # 画点+连线
annotated = results[0].plot(
boxes=False, # 无外框
labels=False, # 无标签
conf=False, # 无置信度
kpt_radius=4, # 点大小
kpt_line=True # 骨架连线
)
cv2.namedWindow("YOLO-Pose", cv2.WINDOW_NORMAL) # 自定义缩放画面
cv2.imshow("YOLO-Pose", annotated)
cv2.waitKey(0)
cv2.destroyAllWindows()保存代码。
效果
终端执行 python pose_yolo.py 指令;
终端打印人体关键点检测结果,包括识别信息、位置、耗时等;


弹窗显示结果


更多效果演示




检测速率较快,识别结果精准。
总结
本文介绍了树莓派 5 结合 OpenCV 实现车牌识别、结合 YOLOv8n 模型实现图像分割、人体关键点检测的板端推理的项目设计,包括对应的算法及模型介绍、测试代码、测试效果演示等,为树莓派在边缘 AI 视觉领域的开发设计和快速应用提供了参考。
我要赚赏金
