找回密码
 立即注册
首页 业界区 业界 源码调试-带你了解下车牌识别的深度学习模型-LPRNet ...

源码调试-带你了解下车牌识别的深度学习模型-LPRNet

予捻 5 小时前

视频演示

源码调试-带你了解下车牌识别的深度学习模型-LPRNet
 
大家好,这里是Coding茶水间。本期我们来调试运行一个经典的深度学习网络——LPRNet,它专门用于车牌识别任务。
LPRNet是由Intel团队开发的端到端深度学习模型,专为车牌识别优化,具有轻量级的特性。
下面我们一步步来探索它的源码、环境搭建和实际运行。
1. LPRNet简介

LPRNet支持识别蓝牌和绿牌(新能源车牌)。它基于PyTorch框架,结合OpenCV进行图像处理,适用于Python 3.0以上版本。
1.png

在GitHub上,作者提供了模型的识别效果展示,包括模糊、污损或倾斜的车牌图片。
2. 获取源码

打开LPRNet的GitHub页面(网址可在视频简介中获取)。点击“Code”按钮下载ZIP压缩包,或使用Git命令克隆仓库:
  1. git clone https://github.com/sirius-ai/LPRNet_Pytorch.git
复制代码
2.gif
下载后解压,使用VS Code或其他IDE打开项目。
3. 源码结构分析

项目结构如下:

  • data:数据集文件夹,包含测试用的车牌图片。这些图片包括模糊、污损或倾斜的样本。
  • load_data.py:用于加载数据集的脚本。
  • model:核心文件夹,包含LPRNet网络结构代码。
  • weights:预训练权重文件(Final_LPRNet_model.pth)。
  • train_LPRNet.pytest_LPRNet.py:训练和测试脚本。
3.png

4. 环境要求


  • Python 3.0+
  • PyTorch
  • OpenCV
  • NumPy 等基础库
确保安装这些依赖后,即可运行。
5. 测试模型性能

使用作者提供的test_LPRNet.py对测试图片进行批量验证,检查模型性能。
6. 单张图片识别

在实际应用中,我们常需要对单张车牌图像进行识别。下面是针对单张图片的自定义代码(基于LPRNet)。代码使用OpenCV读取图片,进行预处理,并输出识别结果。
代码实现
  1. # -*- coding: utf-8 -*-
  2. # /usr/bin/env/python3
  3. '''
  4. 单图片验证LPRNet模型
  5. '''
  6. from data.load_data import CHARS, CHARS_DICT
  7. from PIL import Image, ImageDraw, ImageFont
  8. from model.LPRNet import build_lprnet
  9. from torch.autograd import Variable
  10. import torch.nn.functional as F
  11. import torch.nn as nn
  12. import numpy as np
  13. import argparse
  14. import torch
  15. import time
  16. import cv2
  17. import os
  18. def cv2ImgAddText(img, text, pos, textColor=(255, 0, 0), textSize=12):
  19.     if (isinstance(img, np.ndarray)):
  20.         img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
  21.     draw = ImageDraw.Draw(img)
  22.     fontText = ImageFont.truetype("data/NotoSansCJK-Regular.ttc", textSize, encoding="utf-8")
  23.     draw.text(pos, text, textColor, font=fontText)
  24.     return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
  25. def predict_single_image(image_path):
  26.     # 硬编码参数
  27.     img_size = [94, 24]          # 图像尺寸
  28.     lpr_max_len = 8              # 车牌最大长度
  29.     dropout_rate = 0             # dropout率
  30.     use_cuda = False             # 是否使用CUDA
  31.     pretrained_model = './weights/Final_LPRNet_model.pth'  # 预训练模型路径
  32.    
  33.     # 检查模型文件是否存在
  34.     if not os.path.exists(pretrained_model):
  35.         print(f"[Error] 预训练模型未找到: {pretrained_model}")
  36.         return
  37.    
  38.     # 构建模型
  39.     lprnet = build_lprnet(lpr_max_len=lpr_max_len, phase=False,
  40.                          class_num=len(CHARS), dropout_rate=dropout_rate)
  41.     device = torch.device("cuda:0" if use_cuda else "cpu")
  42.     lprnet.to(device)
  43.    
  44.     # 加载预训练模型
  45.     lprnet.load_state_dict(torch.load(pretrained_model, map_location=device))
  46.     lprnet.eval()
  47.    
  48.     # 读取并预处理图像
  49.     if not os.path.exists(image_path):
  50.         print(f"[Error] 图像未找到: {image_path}")
  51.         return
  52.    
  53.     # 使用OpenCV读取图像
  54.     img_orig = cv2.imread(image_path)
  55.     if img_orig is None:
  56.         print(f"[Error] 无法读取图像: {image_path}")
  57.         return
  58.    
  59.     # 调整图像大小并归一化
  60.     img = cv2.resize(img_orig, (img_size[0], img_size[1]))
  61.     img = img.astype('float32')
  62.     img -= 127.5
  63.     img *= 0.0078125
  64.     img = np.transpose(img, (2, 0, 1))  # HWC -> CHW
  65.    
  66.     # 转换为torch tensor并添加batch维度
  67.     img = torch.from_numpy(img).unsqueeze(0)
  68.     if use_cuda:
  69.         img = img.cuda()
  70.    
  71.     # 预测
  72.     with torch.no_grad():
  73.         prebs = lprnet(img)
  74.    
  75.     # 解码预测结果
  76.     prebs = prebs.cpu().numpy()[0]  # 去掉batch维度
  77.     preb_label = []
  78.     for j in range(prebs.shape[1]):
  79.         preb_label.append(np.argmax(prebs[:, j], axis=0))
  80.    
  81.     # 去除重复和空白标签
  82.     no_repeat_blank_label = []
  83.     pre_c = preb_label[0]
  84.     if pre_c != len(CHARS) - 1:  # 忽略空白标签
  85.         no_repeat_blank_label.append(pre_c)
  86.     for c in preb_label:
  87.         if (pre_c == c) or (c == len(CHARS) - 1):
  88.             if c == len(CHARS) - 1:
  89.                 pre_c = c
  90.             continue
  91.         no_repeat_blank_label.append(c)
  92.         pre_c = c
  93.    
  94.     # 将数字标签转换为字符
  95.     plate_number = ''.join([CHARS[i] for i in no_repeat_blank_label])
  96.    
  97.     # 显示结果
  98.     result_img = cv2ImgAddText(img_orig, plate_number, (10, 30), textColor=(0, 255, 0), textSize=30)
  99.     cv2.imshow('License Plate Recognition', result_img)
  100.     print(f"识别结果: {plate_number}")
  101.     cv2.waitKey(0)
  102.     cv2.destroyAllWindows()
  103. if __name__ == "__main__":
  104.     # 直接在这里指定要测试的图像路径
  105.     test_image_path = "3.png"  # 替换为您的测试图像路径
  106.     predict_single_image(test_image_path)
复制代码
4.gif
7. 运行效果演示

选取一张车牌图片(例如从网上下载的分割好的图像),甚至可以对最后一位字符进行裁切测试。运行代码后,结果会直接叠加在图片上显示。
例如:

  • 测试一张蓝牌:识别准确。
  • 测试一张绿牌(新能源):也支持识别。
5.png

6.png

8. 代码分析

预训练模型加载

设置预训练模型路径(如./weights/Final_LPRNet_model.pth),检查文件存在性。然后使用build_lprnet构建模型,选择设备(CPU或CUDA)。
图像读取与预处理

使用OpenCV读取图片:

  • Resize到94x24分辨率。
  • 转换为float32类型。
  • 减去127.5,使像素值范围变为-127.5到127.5(以0为中心,便于模型收敛)。
  • 乘以0.0078125,使范围接近-1到1(像素归一化)。
  • 转置维度:从HWC (Height, Width, Channels) 转为CHW。
  • 添加batch维度,成为4维张量(batch_size, channels, height, width)。
预测与解码

如果使用CUDA,将图像移到GPU。关闭梯度计算(with torch.no_grad())以加速预测。得到输出后,解码为字符序列,去除重复和空白标签,最终转换为车牌号字符串。
显示结果

使用PIL在原图上添加文本,显示识别结果。
9. 注意事项


  • Mac用户默认使用CPU;NVIDIA显卡用户可启用CUDA加速。
  • 如果想获取单张图片处理代码,欢迎三连+关注,并留言邮箱。
  • 模型适用于已分割的车牌图像;实际应用中可结合检测模型(如YOLO)进行完整识别。
如果想深入了解车牌识别更多内容,欢迎关注Coding茶水间,我会持续输出相关教程!


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册