转换后的结果(以名字保存图片):
在这里插入图片描述

三、目标检测(车牌检测)

简介

  1. 数据集:使用的是用上面CCPD数据集制作的VOC格式的数据集训练,包含蓝牌和绿牌,大约共20完张图片

  2. 模型:yolox、yolov8、及yolov8的修改版

  3. 训练结果:
    请添加图片描述
    在这里插入图片描述

1. 模型训练

1.1 模型训练结果

在这里插入图片描述


四、车牌识别(OCR

简介

  1. 数据集:使用的是上面CCPD制作的数据集
  2. 模型:LPRNet
class="table-box">
模型input-sizeparams(M)准确率
LPR-net94*241.70.995

1. 模型结构介绍

2. 损失函数

2.1 torch.nn.CTCLoss()

一、简介

CTC的全称为Connectionist Temporal Classification,中文译为“连接时序分类”。这一方法主要用于解决神经网络标签和输出不对齐的问题(Alignment problem)。
优势:它不需要强制对标签进行对齐,同时支持可变长度的标签,只需输入序列和监督标签序列即可完成训练。

应用场景:文本识别(scene text recognition)、语音识别(speech recognition)及手写字识别(handwriting recognition)等工程场景。

二、CTCLoss接口说明

第一步: 创建CTCLoss对象

ctc_loss = nn.CTCLoss(blank=len(CHARS)-1, reduction='mean')
 class="hljs-button signin active add_def" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

参数说明:
(1) blank: 空白标签所在的label值,默认为0,需要根据实际的标签定义进行设定;
我们在预测文本时,一般都是有一个空白字符的,整个blank表示的就是空白字符在总字符集中的位置。

(2) reduction: 处理output losses的方式,string类型,可选’none’ 、 ‘mean’ 及 ‘sum’,'none’表示对output losses不做任何处理,‘mean’ 则对output losses (即输出的整个batch_size的损失做操作) 取平均值处理,‘sum’则是对output losses求和处理,默认为’mean’

第二步: 在迭代中调用CTCLoss计算损失值

loss = ctc_loss(log_probs, targets, input_lengths, target_lengths)
 class="hljs-button signin active add_def" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

参数说明:
(1)log_probs: shape=(T, N, C) 的模型输出张量,T: 表示输出的序列的长度; N: 表示batch_size值; C: 表示包含有空白标签的所有要预测的字符集总长度。

如:shape = (50, 32, 5000), 其中的50表示一幅图像最多有50个字, 32为batch_size, 5000表示整个数据集的字符集为5000个。

注: log_probs一般需要经过torch.nn.functional.log_softmax处理后再送入到CTCLoss中。
 class="hljs-button signin active add_def" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

(2)targets: shape=(N, S) 或 (sum(target_lengths))的张量。其中对于第一种类型,N表示batch_size, S表示标签长度。

如:shape =(32, 50),其中的32为batch_size, 50表示每个标签有50个字符。

对于第二种类型,则为所有标签之和,也就是将所有的label合并成了一个1维的数据。

如: tensor([18, 45, 33, 37, 40, 49, 63, 4, 54, 51, 34, 53, 37, 38, 22, 56, 37, 38,33, 39, 34, 46, 2, 41, 44, 37, 39, 35, 33, 40])

注:targets不能包含空白标签。
 class="hljs-button signin active add_def" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

(3)input_lengths: shape为(N)的张量或元组,但每一个元素的长度必须等于T即输出序列长度,一般来说模型输出序列固定后则该张量或元组的元素值均相同;

(4)target_lengths: shape为(N)的张量或元组,其每一个元素指示每个训练输入序列的标签长度,但标签长度是可以变化的;

如: target_lengths = [23, 34,32, … , 45, 34], 表示第一张图片的标签长度为23个字符,第2张图片的标签长度为34个字符。

三、应用实例:“CTCLoss在车牌识别中的应用”

(1)字符集:CHARS

CHARS = ['京', '沪', '津', '渝', '冀', '晋', '蒙', '辽', '吉', '黑',
         '苏', '浙', '皖', '闽', '赣', '鲁', '豫', '鄂', '湘', '粤',
         '桂', '琼', '川', '贵', '云', '藏', '陕', '甘', '青', '宁',
         '新',
         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K',
         'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
         'W', 'X', 'Y', 'Z', 'I', 'O', '-'
         ]
 class="hljs-button signin active mddef add_def" data-title="登录复制" data-report-click="{"spm":"3001.10243"}">' class="code-edithtml active " data-title="运行"> data-report-view="{"spm":"3001.10182","extra":{"index":0,"ab":"exp1"}}" data-report-click="{"spm":"3001.10182","extra":{"index":0,"ab":"exp1"}}" class="code-edithtml-box code-edithtml-box0">运行>

(2)创建CTCLoss对象
因为空白标签所在的位置为len(CHARS)-1,而我们需要处理CTCLoss output losses的方式为‘mean’,则需要按照如下方式初始化CTCLoss类:

ctc_loss = nn.CTCLoss(blank=len(CHARS)-1, reduction='mean')
 class="hljs-button signin active add_def" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

设定输出序列长度T为18,训练批大小N为4,总的字符集长度C如上面CHARS所示为68:

在这里插入图片描述
(3)CTCLoss输入的解释
那么我们在训练一次迭代中打印各个输入形参得出如下结果:
1) log_probs由于数值比较多且为神经网络前向输出结果,我们仅打印其shape出来,如下:
torch.Size([18, 4, 68])

2) 打印targets如下,表示这四张车牌的训练标签,根据target_lengths划分标签后可分别表示这四张车牌:
tensor([18, 45, 33, 37, 40, 49, 63, 4, 54, 51, 34, 53, 37, 38, 22, 56, 37, 38,33, 39, 34, 46, 2, 41, 44, 37, 39, 35, 33, 40]).
共30个数字,因为,上图中的车牌号的实际长度依次为:(7, 8, 8, 7),共30个字符。

3) 打印target_lengths如下,每个元素分别指定了按序取targets多少个元素来表示一个车牌即标签:
(7, 7, 8, 8)

4) 打印input_lengths如下,由于输出序列长度T已经设定为18,因此其元素均是固定相同的:
(18, 18, 18, 18)

其中,只要模型配置固定了后,log_probs不需要我们组装再传送到CTCLoss,但是其余三个输入形参均需要我们根据实际数据集及C、T、N的情况进行设定!

四、使用注意
  1. 官方所给的例程如下,但在实际应用中需要将log_probs的detach()去掉,看注释行,否则无法反向传播进行训练;
    如:
ctc_loss = nn.CTCLoss()
logits = lprnet(images)
log_probs = logits.permute(2, 0, 1)  # for ctc loss: T x N x C
log_probs = log_probs.log_softmax(2).requires_grad_()
# log_probs = log_probs.detach().requires_grad_()
optimizer.zero_grad()

# log_probs: 预测结果 [18, bs, 68]  其中18为序列长度  68为字典数
# labels: [93]
# input_lengths:  tuple   example: 000=18  001=18...   每个序列长度
# target_lengths: tuple   example: 000=7   001=8 ...   每个gt长度
loss = ctc_loss(log_probs, labels, input_lengths=input_lengths, target_lengths=target_lengths)
 class="hljs-button signin active add_def" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. blank空白标签一定要依据空白符在预测总字符集中的位置来设定,否则就会出错;

  2. targets建议将其shape设为(sum(target_lengths)),然后再由target_lengths进行输入序列长度指定就好了,这是因为如果设定为(N, S),则因为S的标签长度如果是可变的,那么我们组装出来的二维张量的第一维度的长度仅为min(S)将损失一部分标签值(多维数组每行的长度必须一致),这就导致模型无法预测较长长度的标签;

  3. 输出序列长度T尽量在模型设计时就要考虑到模型需要预测的最长序列,如需要预测的最长序列其长度为I,则理论上T应大于等于2I+1,这是因为CTCLoss假设在最坏情况下每个真实标签前后都至少有一个空白标签进行隔开以区分重复项;

  4. 输出的log_probs除了进行log_softmax()处理再送入CTCLoss外,还必须要调整其维度顺序,确保其shape为(T, N, C)!


🌟完整代码

   如果您希望获取博文中提到的所有实现相关的完整资源文件(包括测试图片、视频、Python脚本、UI文件、训练数据集、训练代码、界面代码等),这些文件已被全部打包。以下是完整资源包的截图

在这里插入图片描述

您可以通过下方演示视频视频简介部分进行获取

演示视频: 基于深度学习的车牌检测识别系统(yolov8/界面版本二)

总结

本篇文章将通过实战案例,演示如何使用Python结合OpenCV来实现车牌识别。整个过程包括图像预处理车牌定位车牌字符分割,以及模板匹配来输出识别结果。此项目在智能交通车辆管理等领域有着广泛的实际应用价值。通过自动识别车牌信息,可以实现车辆追踪违章查询停车场管理等功能,显著提升交通管理的效率与准确性。该项目也是学习车牌识别技术的一个良好案例。

data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/weixin_71667732/article/details/142754778","extend1":"pc","ab":"new"}">>
注:本文转载自blog.csdn.net的大学生毕业题目的文章"https://blog.csdn.net/weixin_71667732/article/details/142754778"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!