问题描述
将cv2.VideoCapture()
捕捉到的图像使用cv2.line()
、cv2.rectangle()
等函数执行绘图操作时,原始 np.ndarray
格式的图像被转为 cv2.UMat
格式,且绘图失败。
问题背景
调用cv2.VideoCapture()
实时拉取摄像头媒体流并进行显示,涉及到两种情况:
- 直接在原视频帧上进行绘图而后调用
cv2.imshow()
显示,没有报错; - 读取到原始视频帧之后,调用神经网络模型进行处理(其间经历了
np.ndarray → torch.Tensor → np.ndarray
的格式转换),在处理后的视频帧上进行绘图操作,出现了前述问题。
解决方案
- 通过对变量的跟踪发现,原始
np.ndarray
格式的图像是内存连续的,而经神经网络模型处理后的图像为内存非连续,具体可通过对应变量的flags
属性查看该张量是否连续:
其中,print(img_in.flags) # C_CONTIGUOUS : True # F_CONTIGUOUS : False # OWNDATA : False # WRITEABLE : True # ALIGNED : True # WRITEBACKIFCOPY : False # UPDATEIFCOPY : False
C_CONTIGUOUS : False
表示行不连续,F_CONTIGUOUS : False
则表示列不连续。 - 调用
np.ascontiguousarray()
函数,将经过神经网络模型处理后的图像强制转化为内存连续,再执行绘图操作,则该问题解决:img_out = np.ascontiguousarray(img_out) # img_out 为经网络处理后的图像
- 调用
copy()
函数,通过显式复制,原变量也能变为内存连续,但推荐使用np.ascontiguousarray()
函数,因为copy()
函数执行了深拷贝,增加了资源占用。