yolov5-目标检测-解决调用opencv显示中文标签时出现乱码状况

1.1问题描述

如下图所示,在利用yolov5进行目标检测时中文标签全部是??????乱码。

1.2问题定位

一般的目标检查模型绘图代码等其他设置放在utils文件,定位到/utils/utils.py,yolov5的绘框函数为plot_one_box,选择ctrl+f 查找plot_one_box函数,其中使用了cv2.putText()函数,而使用cv2.putText()只能显示英文字符,中文会出现乱码问题。

1.3解决原理

讲cv2格式图片转换为PIL使用PIL在图片上绘制添加中文,可以指定字体文件,然后再转换回去。

大体思路:
1)OpenCV图片格式转换成PIL的图片格式;
2)使用PIL绘制文字;
3)PIL图片格式转换成OpenCV的图片格式;

例子函数

from PIL import Image, ImageFont, ImageDraw
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # cv2和PIL中颜色的hex码的储存顺序不同
pilimg = Image.fromarray(cv2img)
 
# PIL图片上打印汉字
draw = ImageDraw.Draw(pilimg)  # 图片上打印
font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8")  # 参数1:字体文件路径,参数2:字体大小
draw.text((0, 0), "Hi,我是诗shi", (255, 0, 0), font=font)  # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
 
# PIL图片转cv2 图片
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)

2实际解决

2.1 重写plot_one_box函数

重写yolov5文件夹中的utils/utils.py中的plot_one_box 函数。
重写后如下所示

def plot_one_box(x, img, color=None, label=None, line_thickness=None):
    cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img_PIL = Image.fromarray(cv2img)
    font = ImageFont.truetype('data/font/HuaWenXinWei-1.ttf', 16)
    # Plots one bounding box on image img
    tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thickness
    color = color or [random.randint(0, 255) for _ in range(3)]
    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
    cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if label:
        
        draw = ImageDraw.Draw(img_PIL)
        text_size = draw.textsize(label, font)
        draw.text((c1[0], c1[1]-16), label, (255, 0, 0), font=font)
        # draw.text((c1[0], c1[1]-16), label,  fill=(0, 0, 0), font=font)
        draw.rectangle((c1, c2))
        draw.rectangle((c1[0], c1[1], c1[0] + text_size[0], c1[1] - text_size[1] - 3))

        cheng = cv2.cvtColor(np.array(img_PIL), cv2.COLOR_RGB2BGR)
        # old
        # tf = max(tl - 1, 1)  # font thickness
        # t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
        # c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
        # cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled
        # cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
    return cheng

2.2修改调用plot_one_box函数的其他语句

2.2.1 修改plot_images函数中调用plot_one_box的语句

修改yolov5文件夹中的utils/utils.py中的plot_images函数。
将语句调用plot_one_box(box, mosaic, label=label, color=color, line_thickness=tl)
修改为如下语句(就只改了一行,就是我注释掉的那行,前面家mosaic用来接受返回值)

if gt or conf[j] > 0.3:  # 0.3 conf thresh
   label = '%s' % cls if gt else '%s %.1f' % (cls, conf[j])
   mosaic = plot_one_box(box, mosaic, label=label, color=color)
   # plot_one_box(box, mosaic, label=label, color=color, line_thickness=tl)
2.2.2 修改detect.py中调用plot_one_box的语句

直接ctrl+f 查找 plot_one_box 函数
修改为

if save_img or view_img:  # Add bbox to image
  label = '%s %.2f' % (names[int(cls)], conf)
  im0 = plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)

3 运行查看

yolov5-目标检测-解决调用opencv显示中文标签时出现乱码状况_第1张图片
完美解决

你可能感兴趣的:(目标检测,深度学习,深度学习,pytorch,目标检测,图像识别,yolo)