基于OpenCV-Python的全景图拼接:待拼接图像旋转致黑边问题
基于Python和OpenCV的全景图拼接问题
我正在开发一个基于Python和OpenCV的全景图生成项目,采用成对图像拼接的方案,具体步骤如下:
- 使用SIFT检测器提取两张图像的关键点
- 匹配关键点
- 通过RANSAC算法求解将第二张图像变换至目标视角的单应性矩阵(homography matrix)
- 拼接两张图像
遇到的问题
调用cv2.warpPerspective(imgs[1], M, shape)得到的图像(imgs[1]为右侧图像,M为单应性矩阵,shape是结果图像尺寸)会向左轻微旋转,导致拼接后的图像边缘与水平轴不垂直,右上角出现黑边。继续拼接下一张图像时,该黑边会被识别为左侧图像的一部分,最终出现在图像拼接的缝隙中。
参考代码结构
其他采用相同方法实现全景图的开发者,使用以下代码结构能得到左右边缘垂直的正常图像:
img1 = cv2.cvtColor(imgs[1], cv2.COLOR_BGR2GRAY) # 右侧图像转灰度图 img2 = cv2.cvtColor(imgs[0], cv2.COLOR_BGR2GRAY) # 左侧图像转灰度图 # 创建SIFT检测器对象 sift = cv2.xfeatures2d.SIFT_create() kp1, des1 = sift.detectAndCompute(img1, None) # 提取右侧图像的关键点和描述符 kp2, des2 = sift.detectAndCompute(img2, None) # 提取左侧图像的关键点和描述符 # 创建暴力匹配器对象 match = cv2.BFMatcher() # 用暴力匹配器寻找两幅图像的匹配点,返回每个关键点的前2个匹配结果 matches = match.knnMatch(des1, des2, k=2) good = [] # 筛选并保存优质匹配点 for m,n in matches: if m.distance < 0.8*n.distance: good.append(m) MIN_MATCH_COUNT = 10 # 如果匹配点数量大于阈值 if len(good) > MIN_MATCH_COUNT: # 整理关键点列表,定义源点和目标点 src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]) dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]) # 求解单应性矩阵M M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0) # h,w = img1.shape # 右侧图像的高和宽 # pts = np.float32([[0,0], [0,h-1], [w-1, h-1], [w-1,0]]).reshape(-1,1,2) # 用单应性矩阵计算透视变换后的点 # transform = cv2.perspectiveTransform(pts, M) # 以下代码用于显示重叠区域(可选) # img2 = cv2.polylines(img2, [np.int32(transform)], True, 255, 3, cv2.LINE_AA) # plt.imshow(img2) else: print("匹配点数量不足。") # 拼接两幅图像 dst = cv2.warpPerspective(imgs[1], M, (imgs[0].shape[1] + imgs[1].shape[1], imgs[0].shape[0])) dst[0:imgs[0].shape[0], 0:imgs[0].shape[1]] = imgs[0] # 以RGB格式显示拼接后的图像 plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
我的项目GitHub仓库:https://github.com/angepl/panoramaTest.git
内容的提问来源于stack exchange,提问作者Evangelos Platanas
相关产品推荐
相关产品推荐

