本次介绍的是检测识别埃及的车牌,在国内,这种的数据集还是相对匮乏的,在收集/购买数据集之后对数据集进行了整理,发现埃及的车牌不是简单的26个字母和10个数字进行组合。
这里就简单的介绍一下吧,在调研过程中发先,埃及车牌数据集有两种类型,分别是
nc = 27
{'0':'1', '1':'2', '2':'3', '3':'4', '4':'5', '5':'6', '6':'7','7':'8', '8':'9', '9':'A', '10':'B', '11':'C', '12':' D ', '13':'E','14':'F', '15':'G', '16':'H', '17':'K', '18':'L','19':'M','20':'N', '21':'Q','22':'R','23':'S', '24':'T', '25':'W', '26':'Y'}?
nc = 26 (少 Q )
{'0':'1', '1':'2', '2':'3', '3':'4', '4':'5', '5':'6', '6':'7','7':'8', '8':'9', '9':'A', '10':'B', '11':'C', '12':' D ', '13':'E','14':'F', '15':'G', '16':'H', '17':'K', '18':'L','19':'M','20':'N', '21':'R','22':'S', '23':'T', '24':'W', '25':'Y'}
由于没有埃及的朋友,在网上也没有找到准确的说法,到底有没有字母Q,好在这个不重要,按类别多的走就行了。
然后就开始训练,这个训练其实没什么好说的,只是普通的训练。重点在detect上
由于车牌检测,想把车牌直接输出在image右上角,或者将车牌输出到txt文件中,方便下一步操作
因此对detect.py进行以下改进
在detect.py有以下参数,这个参数就是用来保存txt文件的,然后默认是不保存的
parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
?因此我们需要对这样代码进行改进,改进后的
parser.add_argument('--save-txt', default= True, action='store_true', help='save results to *.txt')
这样我们就能保存到txt了,但是这样的保存的内容,不仅有每个框位置的坐标,而且是乱序的,不是完全从左到右或者从右到左进行排序的
还需要做下一步的改进,如果不需要在image上显示label,可以将这个参数关掉
parser.add_argument('--hide-labels', default= False, action='store_true', help='hide labels')
修改后:
parser.add_argument('--hide-labels', default= True, action='store_true', help='hide labels')
这样图片上就不会显示类别了,conf也是一样的,修改后就不会显示置信度分数了
接下来就解决有序保存的问题
# for *xyxy, conf, cls in reversed(det):
# if save_txt: # Write to file
# # xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
# # line = (cls, *xywh, conf) if save_conf else (cls, *xywh) # label format
#
# line = (cls, conf) if save_conf else (cls,) # label format
# with open(txt_path + '.txt', 'a') as f:
# # f.write(('%g ' * len(line)).rstrip() % line + '\n')
# f.write(('%g ' * len(line)).rstrip() % line + ' ')
?注释以下代码
将下面代码添加到原来注释的地方
# 映射字典
class_mapping = {'0':'1', '1':'2', '2':'3', '3':'4', '4':'5', '5':'6', '6':'7','7':'8', '8':'9', '9':'A', '10':'B', '11':'C', '12':'D', '13':'E','14':'F', '15':'G', '16':'H', '17':'K', '18':'L', '19':'M','20':'N','21':'R', '22':'S', '23':'T', '24':'W','25':'Y'}
# 提取第一列并对Tensor进行排序
_, indices = torch.sort(det[:, 0], descending=True)
# 根据排序后的索引重新排列原始Tensor
sorted_tensor = det[indices]
for *xyxy, conf, cls in reversed(sorted_tensor):
if save_txt: # Write to file
cls = str(int(cls.item()))
mapped_label = class_mapping.get(cls,cls) # 获取映射后的类别,如果没有映射,则保持原类别
line = (mapped_label, conf) if save_conf else (mapped_label,) # 使用映射后的结果
with open(txt_path + '.txt', 'a') as f:
f.write(('%s ' * len(line)).rstrip() % line + ' ')
这个是从左到右的排序,如果是需要从右到左,就不需要descending=True了,直接删掉就可以了提取第一列进行排序是根据x的大小排序。
这样就修改完了,快去试试吧,如果有问题或者不懂的地方,欢迎在评论区讨论