解决’FreeTypeFont’对象没有’getsize’属性的报错

运行YOLOv5时出现警告,但不影响正常训练。问题出在 库 Pillow 中的 getsize 函数,getsize已弃用,将在Pillow 10(2023-07-01)中删除。

python3– Pillow10 ‘FreeTypeFont‘ object has no attribute ‘getsize‘报错解决_freetypefont' object has no attribute 'getsize-CSDN博客

上述博客中第一种方法是降低 Pillow 版本,没尝试。

第二种方法就是用 getbbox 函数来替换 getsize 函数,但又引发警告,

w, h = self.font.getbbox(label)  # text width, height valueerror: too many values to unpack

(expected 2)

根据错误提示,跳到对应位置,在该行加上 [2:],即只取后两位数字。(下面做了更新)

        getbbox  方法返回的四个整数值分别代表了一个矩形框的坐标信息,用于表示文本所占据的空间。这四个整数值分别表示左上角和右下角 getbbox() 的坐标:
        1.第一个返回的整数值是左上角的x坐标。
        2.第二个返回的整数值是左上角的y坐标.
        3.第三个返回的整数值是右下角的x坐标。
        4.第四个返回的整数值是右下角的y坐标。

修改一下———————————————————————————————-

这位网友说的是正确的,之前草率了。右下角坐标减去左上角坐标才是比较严谨的做法。这里直接取后两位也不影响结果的原因是,左上角坐标为(0,0)。

还是根据错误提示,跳到对应位置,如下修改:

# w, h = self.font.getsize(label)  # text width, height   ##这行注释掉


x0, y0, x1, y1 = self.font.getbbox(label)  # text width, height    ## 粘贴这两行
w, h = x1-x0, y1-y0

找到对应YOLOv5中的代码来举例,自己稍微修改了一下,仅供参考。需要导入YOLOv5中的一些代码,我就直接 import 了,并没有复制在以下代码中。

""" YOLOv5-7.0"""
import cv2
from utils.general import is_ascii
from PIL import Image, ImageDraw
from utils.plots import check_pil_font
import numpy as np

# utils 文件下的 plots.py 文件
class Annotator:
    # YOLOv5 Annotator for train/val mosaics and jpgs and detect/hub inference annotations
    def __init__(self, im, line_width=None, font_size=None, font='Arial.ttf', pil=False, example='abc'):
        assert im.data.contiguous, 'Image not contiguous. Apply np.ascontiguousarray(im) to Annotator() input images.'
        non_ascii = not is_ascii(example)  # non-latin labels, i.e. asian, arabic, cyrillic
        self.pil = pil or non_ascii
        if self.pil:  # use PIL
            print('use PIL')
            self.im = im if isinstance(im, Image.Image) else Image.fromarray(im)
            self.draw = ImageDraw.Draw(self.im)
            self.font = check_pil_font(font='Arial.Unicode.ttf' if non_ascii else font,
                                       size=font_size or max(round(sum(self.im.size) / 2 * 0.035), 12))
        else:  # use cv2
            print('use cv2')
            self.im = im
        self.lw = line_width or max(round(sum(im.shape) / 2 * 0.003), 2)  # line width

    def box_label(self, box, label='', color=(128, 128, 128), txt_color=(255, 255, 255)):
        # Add one xyxy box to image with label
        if self.pil or not is_ascii(label):
            self.draw.rectangle(box, width=self.lw, outline=color)  # box
            if label:
                w, h = self.font.getsize(label)  # text width, height
                x0, y0, x1, y1 = self.font.getbbox(label)  # text width, height
                w2, h2 = x1-x0, y1-y0
                w3, w4 = self.font.getbbox(label)[2:]  # text width, height
                print(w, h, '   w h')
                print(x1, y1, x1, y1, '  x1, y1, w1, h1')
                print(w2, h2, '  w2, h2')
                print(w3, w4, '  w3, w4')
                outside = box[1] - h >= 0  # label fits outside box
                self.draw.rectangle(
                    (box[0], box[1] - h if outside else box[1], box[0] + w + 1,
                     box[1] + 1 if outside else box[1] + h + 1),
                    fill=color,
                )
                # self.draw.text((box[0], box[1]), label, fill=txt_color, font=self.font, anchor='ls')  # for PIL>8.0
                self.draw.text((box[0], box[1] - h if outside else box[1]), label, fill=txt_color, font=self.font)
        else:  # cv2
            p1, p2 = (int(box[0]), int(box[1])), (int(box[2]), int(box[3]))
            cv2.rectangle(self.im, p1, p2, color, thickness=self.lw, lineType=cv2.LINE_AA)
            if label:
                tf = max(self.lw - 1, 1)  # font thickness
                w, h = cv2.getTextSize(label, 0, fontScale=self.lw / 3, thickness=tf)[0]  # text width, height
                outside = p1[1] - h >= 3
                p2 = p1[0] + w, p1[1] - h - 3 if outside else p1[1] + h + 3
                cv2.rectangle(self.im, p1, p2, color, -1, cv2.LINE_AA)  # filled
                cv2.putText(self.im,
                            label, (p1[0], p1[1] - 2 if outside else p1[1] + h + 2),
                            0,
                            self.lw / 3,
                            txt_color,
                            thickness=tf,
                            lineType=cv2.LINE_AA)

# 实例化 Annotator 类
image = np.zeros((300, 300, 3), dtype=np.uint8)  # 创建一个示例图像
annotator = Annotator(image, line_width=2, font_size=12, font='Arial.ttf', pil=True)

# 定义 box 坐标和标签
box = (10, 20, 30, 40)    # (x0, y0, x1, y1)
label = 'example label'

# 调用 box_label 方法
annotator.box_label(box, label, color=(255, 0, 0), txt_color=(255, 255, 255))

.

物联沃分享整理
物联沃-IOTWORD物联网 » 解决’FreeTypeFont’对象没有’getsize’属性的报错

发表评论