Python OpenCV使用cvtColor的dst参数复用三维numpy数组内存报错如何解决
报错原因
你遇到的报错是因为三维数组(H, W, NUM_BUFFERS)取最后一维切片[:, :, i]得到的numpy视图是非连续内存存储的,OpenCV的函数参数要求传入的dst目标数组是连续内存结构,非连续视图无法识别,就会抛出Expected Ptr<cv::UMat> for argument 'dst'的错误。
解决方案
方案1:调整维度顺序(推荐)
把缓冲区维度放在最前面,构建形状为(NUM_BUFFERS, H, W)的数组,此时取第i个缓冲区gray_frames_array[i]得到的是连续内存视图,完全不需要额外分配内存,符合复用需求,修改后的完整代码如下:
import cv2 import numpy as np # Access camera cap = cv2.VideoCapture(0) cv2.namedWindow('Main process') # Confirm we are able to acquire images (and initialize the frame variable) ret, rgb_frame = cap.read() if ret is False: print('Error, unable to acquire frame...') exit(0) NUM_BUFFERS = 3 # 调整维度顺序:缓冲区数量在前,高和宽在后 gray_frames_array = np.zeros( (NUM_BUFFERS, rgb_frame.shape[0], rgb_frame.shape[1]), dtype=rgb_frame.dtype) i = 0 while True: ret, _ = cap.read(rgb_frame) if ret is False: print('Error, unable to acquire frame...') exit(0) # 直接取第i个缓冲区的连续视图作为dst cv2.cvtColor(src=rgb_frame, code=cv2.COLOR_BGR2GRAY, dst=gray_frames_array[i]) cv2.imshow('Main process', gray_frames_array[i]) if cv2.waitKey(5) == 27: break # 切换下一个缓冲区 i = (i+1) % NUM_BUFFERS cap.release() cv2.destroyAllWindows() print('done')
方案2:保留原维度布局的兼容方法
如果你确实需要保留(H, W, NUM_BUFFERS)的维度布局,创建数组时指定order='F'(Fortran列优先存储),此时[:, :, i]的切片就是连续视图,可以直接传入OpenCV函数,仅需要修改数组创建代码:
gray_frames_array = np.zeros( (rgb_frame.shape[0], rgb_frame.shape[1], NUM_BUFFERS), dtype=rgb_frame.dtype, order='F')
内容的提问来源于stack exchange,提问作者hugo
相关产品推荐
相关产品推荐

