最近再弄视频处理,是在程序里处理其他程序员传给我的一帧一帧图片,使用的语言是python+C,整个处理后的视频监控显示由纯python加C库调用,在处理的过程中本来打算使用wx自带的绘图设备dc去做这些处理,由于数据量比较大,涉及到多路显示,我不得不把数据处理部分分线程去做,结果运行20多分钟程序就会死在gtk库里,跟wxpython项目组交流后,原因是不可以使用多线程操作GUI资源,而dc也属于一种gui资源,不可以分线程使用,但要是都写进主线程,我的主线程开销会很大,程序和图像更新变得非常卡顿。后来偶然间尝试试用了一下在子线程中使用opencv去处理图像,发现没有什么问题,而且,使用opencv的rtsp接口抓取视屏,可以省略掉自己对视频图像解码的过程,更高效一些,但是在做图像叠加的时候遇到了问题,我们的数据是存进内存中的,使用的时候也直接调用内存,python opencv读取图像只提供了文件形式的读取,没有提供内存数据怎么处理,网上也基本查不到什么相关信息。尝试了很多方法之后,opencv读取数据之后是以矩阵形式存放的,也就是CV::MAT,内存里的数据是一堆unicode的char型数组,这样无非也就是转个码,变换下形式,经过实验,一下代码可行:
import numpy as np
import array
from PIL import Image
self.cap = cv2.VideoCapture("rtsp://10.0.14.60:554/vm_stream&&channel=0")
while(self.timeToQuit.is_set() == False and self.cap.isOpened()):
flag, im_rd = self.cap.read()
image = Image.frombuffer("RGB", (112, 112), cRgbbuf) #cRgbbuf是内存中的RGB888数据,h.264和YUV,RGB565等的可以使用ffmpeg的C代码去转
imageInput = np.asarray(image.transpose(Image.FLIP_TOP_BOTTOM)) #得到的图像时倒着的,需要上下翻转一下
#下面是敏感区域的图片叠加
image = cv2.cvtColor(im_rd, cv2.COLOR_BGR2RGB)
roi = image[picSize[1]-132:picSize[1]-20, 0:112]
add_img = cv2.addWeighted(imageInput, 0.8, roi, 0.2, 0)
image[picSize[1]-132:picSize[1]-20, 0:112] = add_img
得到的img就是处理完,图片叠加过的一帧图片
然而,事情并没有想象中的顺利,发现opencv不支持中文输入,
cv2.putText没法输入中文,我要是再用PIL去来回转一遍,或者freetype去做字体添加,会非常麻烦,而且没效率,仅仅是上面的图片操作就已经使我的cpu使用率上升300%,我可能会舍弃掉这种操作,直接使用PIL试试
PIL确实是号称第三方的官方库,用来做图像处理非常强大,解决了我上面的所有问题
Image.frombuffer可以替换为 Image.frombytes这样可以省略翻转的过程