如下图所示,在利用yolov5进行目标检测时中文标签全部是??????乱码。
一般的目标检查模型绘图代码等其他设置放在utils文件,定位到/utils/utils.py
,yolov5的绘框函数为plot_one_box
,选择ctrl+f 查找plot_one_box
函数,其中使用了cv2.putText()
函数,而使用cv2.putText()
只能显示英文字符,中文会出现乱码问题。
讲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)
重写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
修改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)
直接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)