使用 Monkey Patch 解决 Sahi 可视化的中文乱码问题

其实如果是对算法的输出结果进行可视化的话,使用 Pillow 库是完全没有问题的。但是存在着这样一种情况,我们调用的公共包当中,里面已经有了可视化的接口,但是使用的是 OpenCV 中的 cv2.putText 进行可视化的。正常来说,因为 OpenCv 对中文的支持不足,直接调用的话,显示在图片上的 label 名肯定是一串问号,也就是乱码,这时,就有几个选择:

  1. 自己从零实现一个可视化的功能,使用 Pillow 或者别的库进行可视化
  2. pip 安装完 Sahi 库之后,手动进入到库内修改相关的代码,将 cv2.putText 改成 Pillow 相关的方法

第一个选择虽然不是不可行,但是重复造轮子确实挺浪费时间的,至于第二个选择,对于我来说存在一个问题,因为我这个算法是要打包成 whl 安装包的,我不可能每安装一次,就去手动修改一下 Sahi 的文件,或者是替换一下它的文件,所以也只能否决了。

但是我想到第三种方法:

  1. 使用 Monkey Patch 来替换 OpenCv 的 cv2.putText 函数

之前虽然看到过 Monkey Patch 这种用法,但是一直没有遇到什么相关的场景,对它的理解也是懵懵懂懂,觉得这玩意真的有用吗?今天终于让我遇到了比较合适的场景:

无需修改公有库的源文件,就可以修改其功能。

下面给出一个初版的代码,因为并没有将 cv2.putText 的全部功能都实现了,只是实现了些基础的特性:

import types
from typing import Optional, Sequence

import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont

font_path = 'SimHei.ttf'

def putText(self,
            img: np.ndarray,
            text: str,
            org: Sequence[int],
            fontFace: int,
            fontScale: Optional[float],
            color: Sequence[int],
            thickness: Optional[float] = 1,
            lineType=cv2.LINE_AA,
            bottomLeftOrigin=True,
            ):
    base_size = 30
    fontSize = base_size * fontScale
    img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

    draw = ImageDraw.Draw(img_pil)
    fontStyle = ImageFont.truetype(font=font_path,
                                   size=int(fontSize),
                                   encoding='utf-8')

    draw.text(xy=(int(org[0]), int(org[1]-fontSize)),
              text=text,
              fill=color,
              font=fontStyle)
    img_cv2 = cv2.cvtColor(np.asarray(img_pil), cv2.COLOR_RGB2BGR)
    img[...] = img_cv2

cv2.putText = types.MethodType(putText, None)

后续再使用 Sahi 进行可视化的时候,就可以正常显示中文了。

  • 参数列表的 self 是需要的,可以替换为任意的参数名,因为 OpenCv 调用的时候第一个会传入一个隐藏的参数。
  • SimHei.ttf 字体文件得自己找个地方下载一下,可以替换为别的字体
  • 因为 cv2.putText 就是原图上绘制,没有返回值的,所以我也将没有用返回值,直接将绘制得结果又放回了 img

简单的打了个小补丁,不考虑格式化的话,大概 10 行代码左右就解决了 Sahi 中文乱码问题(虽然在大型项目中不推荐这么用,可能会考虑不周,导致可怕的后果,甚至更谨慎一点,可以将最后一行放入一个可视化的 if 语句内,只有收到可视化的布尔参数,才使用 Monkey Patch 进行替换,将对其他可能用到 cv2.putText 函数的地方,影响降低到最小)

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值