Tangwx

Tangwx

博客网站

yolov5检测框显示中文标签

yolov5 检测框显示中文标签#

注意:本注解对应 yolov5 的 5.0 版本!!!#

前言

1、有中文标签的数据集

2、yolov5 代码修改为支持中文标签


前言#

​ 很多人在训练yolov5目标检测的时候,标签只能显示英文的。怎么样才可以训练一个可以检测物体并且显示中文标签的模型呢。下面我们来一步一步的做。

1、有中文标签的数据集#

​ 首先在收集数据集的时候,打部分公开的数据集,标签都是英文的,格式都是 voc 格式,文件是 xml 文件,当然 xml 文件格式的标签是特别直观的,直观的知道标签中的图片大小,标注位置,还有标注的类别。虽然训练 yolov5 的时候用的是 yolo 格式的数据集,但是大家在标注数据集的时候尽量标注为 voc 格式,这样方便又直观,然后训练 YOLOv5 模型的时候有代码可以一键转换。代码博客:目标检测 --- 数据集格式转化及训练集和验证集划分

​ 自己制作中文标签的数据集的话,利用 labelimg 这个工具标注数据集的时候,将标签改成中文就好了,具体的教程博客:目标检测 --- 利用 labelimg 制作自己的深度学习目标检测数据集

​ 如果这里有一份英文标签的 voc 格式的数据集,可以利用如下的代码将数据集中的英文标签转为中文标签。

# encoding:utf-8

import os
import xml.etree.ElementTree as ET


count = 0

list_xml = []

dict = {"ball": "足球",

        "messi": "梅西",
        }


openPath = "VOCdevkit\VOC2007\Annotations"
savePath = "VOCdevkit\VOC2007\Annotations1"


fileList = os.listdir(openPath)         # 得到进程当前工作目录中的所有文件名称列表
for fileName in fileList:               # 获取文件列表中的文件
    if fileName.endswith(".xml"):       # 只看xml文件
        print("filename=:", fileName)
        tree = ET.parse(os.path.join(openPath, fileName))
        root = tree.getroot()
        print("root-tag=:", root.tag)   # ',root-attrib:', root.attrib, ',root-text:', root.text)
        for child in root: # 第一层解析
            if child.tag == "object":   # 找到object标签
                print(child.tag)
                for sub in child:
                    if sub.tag == "name":
                        print("标签名字:", sub.tag, ";文本内容:", sub.text)
                        if sub.text not in list_xml:
                            list_xml.append(sub.text)
                        if sub.text in list(dict.keys()):
                            sub.text = dict[sub.text]
                            print(sub.text)
                            count = count + 1
        tree.write(os.path.join(savePath, fileName), encoding='utf-8')

    print("=" * 20)

print(count)
for i in list_xml:
    print(i)

​ 这个代码也可以将中文标签的 voc 格式的数据集转化为英文标签的数据集。如下图所示,将中文和英文的位置调换就可以了。

​ 中文标签的 voc 格式的数据集,可以利用目标检测 --- 数据集格式转化及训练集和验证集划分这篇博客中的代码将 voc 格式的数据集转化为 yolo 数据集,并划分为训练集和验证集。

​ 至此中文标签的数据集就准备好了

2、yolov5 代码修改为支持中文标签#

​ 特别要说明一下,该博客所用的是 yolov5 的 5.0 版本。

​ (1)train.py 文件修改,在 py 文件中的 63 行,代码修改如下:

with open(opt.data, encoding='UTF-8') as f:

​ (2)test.py 文件文件修改,在 py 文件中的 73 行,代码修改如下:

with open(opt.data, encoding='UTF-8') as f:

​ (3)utils/general.py 文件文件修改,在这个代码中导入如下的包:

from PIL import Image, ImageDraw, ImageFont

​ (4)utils/plots.py 文件修改,在 py 文件中的 64 行,修改 plot_one_box 函数,if label 之后的代码改为:

tf = max(tl - 1, 1)  # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
font_size = t_size[1]
font = ImageFont.truetype('msyh.ttc', font_size)
t_size = font.getsize(label)
c2 = c1[0] + t_size[0], c1[1] - t_size[1]
cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled
img_PIL = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_PIL)
draw.text((c1[0], c2[1] - 2), label, fill=(255, 255, 255), font=font)
return cv2.cvtColor(np.array(img_PIL), cv2.COLOR_RGB2BGR)

(5)utils/plots.py 文件修改,在 py 文件中的 144 行,修改 plot_images 函数:

mosaic = plot_one_box(box, mosaic, label=label, color=color, line_thickness=tl)

(6)detect.py 文件修改,在 py 文件中的 178 行,代码修改如下:

im0 = plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)

注意,这个 im0 非常重要,如果你的图片已经框出来了,但是标签上不显示字,那么很有可能就是这个im0= 缺失,这个im0与后面plot_one_box(xyxy, im0里的 im0 要对应

至此为了支持中文标签的代码就修改完了。

​ 如果后面的模型训练和推理测试工作可以参考博客:目标检测 --- 教你利用 yolov5 训练自己的目标检测模型

​ 这里特别要说明一下,就是修改 data 目录下的 yaml 文件的时候,那个标签也一定要对应标注的中文类别。

参考链接:(下文)

YoloV5 实现中文标签目标检测 - 知乎 (zhihu.com)

YoloV5 实现中文标签目标检测#

1、复制 yolov5 工程到本地#

https://github.com/ultralytics/yolov5

2、查看字体#

默认调用C:\Windows\Fonts 下的字体,找个合适的,比如我这次使用simhei.ttf

3、train.py文件#

with open(opt.data) as f:

改为

with open(opt.data, encoding='UTF-8') as f:

4、test.py 文件#

with open(data) as f:

改为

with open(data, encoding='UTF-8') as f:

5、utils/general.py 文件#

导包

from PIL import Image, ImageDraw, ImageFont

6、utils/plot.py 文件#

修改plot_one_box 函数,if label之后的代码改为

if label:
        tf = max(tl - 1, 1)  # font thickness
        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
        font_size = t_size[1]
        font = ImageFont.truetype('MSYH.TTC', font_size)
        t_size = font.getsize(label)
        c2 = c1[0] + t_size[0], c1[1] - t_size[1]
        cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled
        img_PIL = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(img_PIL)
        draw.text((c1[0], c2[1] - 2), label, fill=(255, 255, 255), font=font)

        return cv2.cvtColor(np.array(img_PIL), cv2.COLOR_RGB2BGR)

7、utils/plot.py 文件#

plot_images函数中

plot_one_box(box, mosaic, label=label, color=color, line_thickness=tl)

改为

mosaic = plot_one_box(box, mosaic, label=label, color=color, line_thickness=tl)

8、detect.py 文件#

plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)

改为

im0 = plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。