网格状拼接地毯图像时的轻微错位问题及优化咨询
地毯高分辨率图像拼接优化方案求助
背景与当前方案
我需要制作全清晰的高分辨率地毯合成图像,方法是拍摄地毯不同部位的6张照片后拼接。原本使用Photoshop API,由于Adobe将其整合至仅企业可用的Firefly,转而基于OpenCV开发手动拼接方案。
原始图像按2列3行排列:左列从上到下为图像5、3、1,右列从上到下为图像6、4、2。
曾尝试OpenCV内置的Stitcher类,调整参数后仅部分图像能成功拼接,因此采用手动拼接流程:
- 第一步:两两拼接同行图像(1与2、3与4、5与6),得到3张行拼接结果,效果尚可
- 第二步:将行1与行2拼接,再将结果与行3拼接,最终图像的地毯边缘出现无法消除的轻微错位
现有代码实现
main.py
import cv2 from loader import load_images from stitcher import stitch_images_manual def main(): corrected_images_dir = "out" num_images = 6 # Adjust this to the number of images you have rows = 3 # Number of rows in your grid columns = 2 # Number of columns in your grid # Load images images = load_images(corrected_images_dir, num_images) if len(images) == 0: print("No images loaded.") return # Stitch images in pairs for each row row_images = [] for i in range(rows): start_idx = i * columns pair = [images[start_idx], images[start_idx + 1]] print(f'Stitching row {i + 1} with images {start_idx + 1} and {start_idx + 2}') stitched_row = stitch_images_manual(pair[0], pair[1]) if stitched_row is not None: row_images.append(stitched_row) cv2.imwrite(f'out/stitched_row_{i + 1}.png', stitched_row) print(f'Saved stitched row {i + 1} as stitched_row_{i + 1}.png') else: print(f'Stitching failed for row {i + 1}') return if __name__ == "__main__": main()
stitcher.py
import cv2 import numpy as np from features import detect_and_compute_features from homography import compute_homography from warp import warp_image from resize import resize_image from camera_params import estimate_initial_camera_params, refine_camera_params def stitch_images_manual(image1, image2, scale_percent=50): print(f"Stitching images of shapes: {image1.shape} and {image2.shape}") # # Resize images to medium resolution # image1_resized = resize_image(image1, scale_percent) # image2_resized = resize_image(image2, scale_percent) # Convert images to grayscale gray1 = cv2.cvtColor(image1, cv2.COLOR_BGRA2GRAY) gray2 = cv2.cvtColor(image2, cv2.COLOR_BGRA2GRAY) # Detect SIFT features and compute descriptors keypoints1, descriptors1 = detect_and_compute_features(gray1) keypoints2, descriptors2 = detect_and_compute_features(gray2) # Match features using FLANN matcher FLANN_INDEX_KDTREE = 1 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=10) search_params = dict(checks=500) flann = cv2.FlannBasedMatcher(index_params, search_params) matches = flann.knnMatch(descriptors1, descriptors2, k=2) # Apply ratio test good_matches = [] for m, n in matches: if m.distance < 0.7 * n.distance: good_matches.append(m) if len(good_matches) < 4: print("Not enough good matches to compute homography.") return None # Extract location of good matches points1 = np.zeros((len(good_matches), 2), dtype=np.float32) points2 = np.zeros((len(good_matches), 2), dtype=np.float32) for i, match in enumerate(good_matches): points1[i, :] = keypoints1[match.queryIdx].pt points2[i, :] = keypoints2[match.trainIdx].pt # Compute homography h = compute_homography(points1, points2) if h is None: return None # Get dimensions of input images height1, width1 = image1.shape[:2] height2, width2 = image2.shape[:2] # Determine canvas size based on stitching direction if height1 > height2: canvas_width = max(width1, width2) canvas_height = height1 + height2 else: canvas_width = width1 + width2 canvas_height = max(height1, height2) # Warp the second image to the first image's plane warped_image2 = warp_image(image2, h, (canvas_width, canvas_height)) # Create the stitched image canvas result = np.zeros((canvas_height, canvas_width, 4), dtype=np.uint8) result[0:height1, 0:width1] = image1 # Create a mask of where the warped image has valid pixels mask = np.any(warped_image2 != 0, axis=2) # Paste the warped image pixels into the result image result[mask] = warped_image2[mask] return result
warp.py
import cv2 import numpy as np def warp_image(image, homography, canvas_size): warped_image = cv2.warpPerspective(image, homography, canvas_size) # cv2.imshow("warped",warped_image) # cv2.waitKey(0) # cv2.destroyAllWindows return warped_image
loader.py
import os import cv2 def load_images(image_dir, num_images): images = [] for i in range(1, num_images + 1): image_path = os.path.join(image_dir, f'{i}.png') if os.path.exists(image_path): img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED) if img.shape[2] == 3: img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) images.append(img) print(f'Loaded image {i} with shape {img.shape}') else: print(f'Image {image_path} not found.') return images
homography.py
import cv2 import numpy as np def compute_homography(points1, points2): h, mask = cv2.findHomography(points2, points1, cv2.RANSAC) if h is None: print("Homography computation failed.") return h
features.py
import cv2 def detect_and_compute_features(image): sift = cv2.SIFT_create() keypoints, descriptors = sift.detectAndCompute(image, None) return keypoints, descriptors
已尝试的无效方案
- 手动旋转行拼接结果并重新拼接,效果无改善
- 去除背景后拼接,效果不佳
- 试用多个GitHub开源拼接工具,均出现类似错位问题
优化建议需求
针对地毯图像拼接的错位问题,寻求具体的技术优化方向或代码调整方案。
内容的提问来源于stack exchange,提问作者Karan
相关产品推荐
相关产品推荐

