使用OpenCV warpPerspective拼接全景图背景变黑、图像重叠问题排查
错误原因
- 输出尺寸参数传反
OpenCV中所有size参数的格式为(宽度, 高度),而numpy数组的shape属性返回顺序为(高度, 宽度, 通道数)。你定义的size = (2 * image1.shape[0],image1.shape[1])相当于把输出图的高度设为原图的2倍、宽度和原图一致,完全不符合拼接两张图的需求,也会导致后续变换的像素落点异常,最终背景变黑。 - 单应性矩阵变换逻辑重复求逆
cv2.WARP_INVERSE_MAP标志的作用就是告诉OpenCV,传入的矩阵是目标点到源点的逆变换矩阵,无需额外手动求逆。你既提前手动计算了H的逆矩阵I,又开启了该标志,相当于对H连续求了两次逆,最终传入的变换矩阵等价于原H,完全不符合把img2映射到img1坐标系的需求,直接导致img2错位覆盖img1。 - 重叠区域直接覆盖未做融合
两次调用warpPerspective都是直接写入目标数组,重叠区域会被后写入的img2直接覆盖,没有做过渡处理。 cv2.imshow调用参数错误cv2.imshow的入参格式为cv2.imshow(窗口名字符串, 图像数组),你传入列表作为参数会导致显示异常。- 未兼容彩色图像的数组初始化
如果输入是三通道彩色图像,你初始化img的时候只传入二维尺寸,会生成单通道数组,写入彩色像素会直接出错。
修正后代码
import numpy as np import cv2 def panorama(img1, img2, H, size): # 初始化目标画布,兼容彩色和灰度图 if len(img1.shape) == 3: img = np.full((size[1], size[0], img1.shape[2]), 255, dtype=np.uint8) else: img = np.full((size[1], size[0]), 255, dtype=np.uint8) # 粘贴第一张图 cv2.warpPerspective(img1, np.eye(3), size, dst=img, borderMode=cv2.BORDER_TRANSPARENT) # 粘贴第二张图,二选一:要么传H开WARP_INVERSE_MAP,要么传inv(H)不开该标志 cv2.warpPerspective(img2, H, size, dst=img, flags=cv2.WARP_INVERSE_MAP + cv2.INTER_LINEAR, borderMode=cv2.BORDER_TRANSPARENT) return img # 尺寸定义修正:宽度为img1的2倍,高度和img1一致 h, w = image1.shape[:2] size = (2 * w, h) result = panorama(image1, image2, H, size) cv2.imshow("Panorama", result) cv2.waitKey(0)
如果要解决重叠区域硬覆盖的问题,可以把两次变换的结果分别存为两个掩膜,重叠区域按权重做alpha blending即可。
内容的提问来源于stack exchange,提问作者Anđela Todorović
相关产品推荐
相关产品推荐

