opencv展示汉字及与pillow对比

1、前记

因为opencv不能显示中文(会变成???),所以尝试通过opencv->pillow->opencv这种方式来实现,具体可参考这篇博客。

2、利用pillow展示中文

下面来简述一下使用情况:

# opencv-> pillow
cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
pilimg = Image.fromarray(cv2img)
'''
进行一些操作
'''
# pillow -> opencv
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)

可以显示中文了!
在这里插入图片描述
经过在主机上(cpu:12700F)测试
opencv与pil互转需要 2-3 ms,pil画图(目标检测的可视化,包括bbox绘制,文本输出)需要 10+ ms,算下来一帧的图像处理就在 15+ ms了,在我的主机上速度尚且可以,但是在agx上一帧的图像处理速度在 60+ ms了,达不到实时性要求。

后来,发现了一个好东西——pillow-smid,专门用来加速pillow的库,安装比较简单,见这篇博客,需要注意的是需要先卸载pillow再安装pillow-smid。在我的主机上安装十分顺利,但是在agx上pip安装会报错,具体错误如这个所示,总之就是编译错误。不过github上并没有回复,因此需要自行解决,可见本文最后部分。
——————————————————————————————————————————
pillow-smid的使用方法和pillow一模一样,原先的代码不用变。
加速效果(仅plot部分):

pillow pillow-smid opencv
主机 10+ ms 3~4 ms 2~3 ms
agx 40++ ms 21 ms左右 6~8 ms

虽然整体速度还是不如opencv,而且还需要opencv和pil互转花费额外的时间,但至少解决了中文乱码的问题,在agx上也能保证一帧15fps以上,基本满足使用要求。

如果是在ros中的项目,通过cv_bridge来收发图片,则可以省去opencv的bgr编码与pillow的rgb编码互转步骤,还可以节省少量时间(时间就是慢慢挤出来的,因此发现互转耗费时间的是numpy和Image之间type的互转)。

# numpy -> pillow
pilimg = Image.fromarray(image)
# pillow -> numpy 
npimg = np.array(pilimg)

注意:虽然pillow的图片编码只支持RGB的,但是采用这种办法的图片编码取决于cv_bridge的编码,如果你接收的是BGR格式的图片,那么按照这样的处理,在plot的前中后都是BGR编码的,一定注意通道的顺序,这么做只是为了少一步通道顺序变换。虽然听起来很拗口,但是就是这么NTR,相当于把pillow当opencv用了~

3、 pillow与opencv常用函数

这里列举三个目标检测可视化的常用的函数

注意:pillow 需要提前定义画布、字体样式

from PIL import Image, ImageDraw, ImageFont
# 画布定义
draw = ImageDraw.Draw(pilimg)
# 字体样式,这步非常消耗时间,建议放在循环外面,只执行一次
font = ImageFont.truetype(font_path, 22, encoding="utf-8") 

(1) 画boundbingbox

只画线框

# pillow
# “width=”需要 pillow >= 5.3.0, pillow-smid的版本与pillow的版本不一定一致,
# 比如我用源码安装的pillow-smid-7.0.0,但是里面的pil是5.1.0版本
draw.rectangle((c1,c2),fill=None,outline=color1,width=line_thickness) 
# 低版本pillow替代方法,实现对线宽的控制
draw.line([(x1,y1),(x2,y1),(x2,y2),(x1,y2),(x1,y1)],  width=line_thickness, fill=color1)

# opencv
cv2.rectangle(image,(x1,y1),(x2,y2),color1,thickness=tl, lineType=cv2.LINE_AA)

画实心框

# pillow
draw.rectangle((c1,c2),fill=color1,outline=None)
# opencv
cv2.rectangle(image, c1, c2, color1, cv2.FILLED)
# 或者
cv2.rectangle(image, c1, c2, color1,thickness=-1, lineType=cv2.LINE_AA)

(2) 展示文本

# pillow
draw.text((x1,y1),txt2,color1,font=font)
# opencv
cv2.putText(image, txt2, (x1,y1), 0, tl/3, color1,
           thickness=tf, lineType=cv2.LINE_AA)

(3) 获取文本长度

# pillow
t_size = font.getsize(txt2)
# opencv
t_size = cv2.getTextSize(txt2, 0, fontScale=tf, thickness=tf)[0]

注意:pillow和opencv的区别

  • 矩形框定位
  • pillow是两个点放在一个元组中((x1,x2),(y1,y2));
  • opencv是两个点分开放(x1,x2),(y1,y2)。
  • 颜色
  • pillow只能是元组格式(255,255,255);
  • opencv可以是列表、元组。

4、pillow-smid安装失败解决方法

windows

windows可以直接下载whl文件然后安装,window安装包链接https://www.lfd.uci.edu/~gohlke/pythonlibs/

linux

我用的这个办法,直接在pypi或者github下载源码,放到工作空间目录下的/src,然后catkin_make,之后可以在这个工作空间下使用。

你可能感兴趣的:(经验教训,opencv,pillow,计算机视觉)