OpenCV3.4生成双目深度图时resize视频帧报错排查
你的错误提示ssize.width > 0 && ssize.height > 0直接说明:调用cv2.resize时传入的dst图像宽或高为0(甚至负数),导致函数无法执行。结合你说“8张图标定正常、21张图出问题”的情况,问题大概率出在标定得到的ROI切片参数(x,y,w,h)或者remap后的图像有效性上,具体分析如下:
可能的原因
1. 21张图标定生成的ROI参数无效
用更多图像标定后,OpenCV计算出的校正后ROI区域(x,y,w,h)可能出现以下异常:
- x或y的数值过大,导致
y+h超过remap后图像的高度,或x+w超过图像宽度,切片后得到空图像; - w或h被计算为负数(极端情况,但多图标定如果图像差异大可能出现);
- 标定得到的ROI和当前视频帧的尺寸不匹配(比如标定用的图像分辨率和视频帧分辨率不一样)。
2. remap映射矩阵与视频帧尺寸不匹配
如果21张图标定用的图像分辨率和当前读取的视频帧分辨率不一致,mapx1/mapy1的尺寸会和frame尺寸不兼容,导致remap后生成空图像或异常尺寸的图像,后续切片自然会出问题。
3. 切片逻辑的边界处理缺失
如果没有对ROI参数做边界校验,当标定得到的ROI超出图像范围时,直接切片会得到无效尺寸的图像。
排查与解决步骤
第一步:定位问题节点
在代码中加入打印语句,确认每一步的图像尺寸:
ret, frame = cap1.read() ret, frame2 = cap2.read() # 先确认视频帧本身有效 print("Original frame shape:", frame.shape) dst = cv2.remap(frame, mapx1, mapy1, cv2.INTER_LINEAR) print("After remap, dst shape:", dst.shape) # 查看remap后的图像尺寸 dst = dst[y:y + h, x:x + w] print("After slicing, dst shape:", dst.shape) # 查看切片后的尺寸,这里大概率会出现(0,0,3)或类似无效值
如果切片后的宽高≤0,说明问题确实出在ROI切片环节。
第二步:检查标定的ROI参数
加载21张图的标定文件后,直接打印x,y,w,h的数值:
print("ROI params: x={}, y={}, w={}, h={}".format(x, y, w, h))
对比8张图标定得到的参数,看看是不是21张的参数有异常(比如w为负数,或者x+w远大于remap后图像的宽度)。
第三步:验证映射矩阵与视频帧的尺寸兼容性
打印映射矩阵和视频帧的尺寸,确认两者匹配:
print("mapx1 shape:", mapx1.shape) print("frame shape:", frame.shape)
映射矩阵的高度和宽度必须和视频帧的高度、宽度完全一致(比如视频帧是(480,640,3),mapx1应该是(480,640))。如果不一致,说明标定用的图像分辨率和视频帧不同,需要先把视频帧resize到标定图像的分辨率再执行remap。
第四步:修复ROI切片逻辑
如果ROI参数超出图像范围,手动添加边界校验,或者用cv2.getOptimalNewCameraMatrix重新计算合适的ROI:
# 假设你有标定得到的左相机矩阵camera_matrix_left和畸变系数dist_coeffs_left frame_width, frame_height = frame.shape[1], frame.shape[0] # 重新计算适配当前帧尺寸的最优相机矩阵和ROI new_cam_mat, roi = cv2.getOptimalNewCameraMatrix(camera_matrix_left, dist_coeffs_left, (frame_width, frame_height), 1, (frame_width, frame_height)) x, y, w, h = roi # 强制保证ROI在图像范围内 x = max(0, x) y = max(0, y) w = min(w, frame_width - x) h = min(h, frame_height - y)
这样就能确保切片后的图像尺寸有效,不会触发resize的错误。
内容的提问来源于stack exchange,提问作者gaetano ma

