基于Python的加权平均融合实现图像全景拼接且去除缝隙

目标:

将数张有重叠部分的图像通过特征点检测,匹配,图像变换拼成一幅无缝的全景图。
待拼接的上方图片
在这里插入图片描述
待拼接的下方图片
在这里插入图片描述
#拼接成功后的图片
在这里插入图片描述
在图像拼接中首先利用SIFT算法提取图像特征进而进行特征匹配,继而使用RANSAC算法对特征匹配的结果进行优化,接着利用图像变换结构进行图像映射,最终进行图像融合。

在图像拼接过程中,运用SIFT局部描述算子检测图像中的关键点和特征,SIFT特征是基于物体上的一些局部外观的兴趣点而与影像的大小和旋转无关。对于光线、噪声、些微视角改变的容忍度也相当高,所以用来检测要拼接图像的特征及关键点就很有优势。而接下来即步骤三是找到重叠的图片部分,连接所有图片之后就可以形成一个基本的全景图了。匹配图片最常用的方式是采用RANSAC(RANdom SAmple Consensus, 随机抽样一致),用此排除掉不符合大部分几何变换的匹配。之后利用这些匹配的点来估算单应矩阵”(Homography Estimation),也就是将其中一张图像通过关联性和另一张匹配。

在计算特征点会出现左图多个相同目标和右图的目标匹配成功所以我的处理
是将左图右边的1/5,右图左边的1/5进行提取图像特征,并进行特征匹配。
代码实现如下:
H是3x3视角变换矩阵
,img_origcorners_orig = np.array([[0, 0, imageA.shape[0], imageA.shape[0]],
[0, imageA.shape[1], 0, imageA.shape[1]],
[1, 1, 1, 1]])
transform_corners = np.matmul(H, corners_orig)
transform_corners(34) 结果的每一列的前2维分别是img_orig在warpPerspective images图像中的四个corners坐标
x’=(h11
x+h12y+h13)/(h31x+h32y+1),y’=(h21x+h22y+h23)/(h31x+h32*y+1)变换得到该点在另一幅图像的位置。
在这里插入图片描述
变换结果
在这里插入图片描述

		(imageB, imageA) = images
        imagea=copy.copy(imageA)
        imageb = copy.copy(imageB)
        imagea=self.Convert(imagea,int(imageA.shape[1] / 5),imageA.shape[1])
        imageb=self.Convert(imageb, 0,imageB.shape[1]-int(imageB.shape[1] / 5))
        (kpsA, featuresA) = self.detectAndDescribe(imagea)
        (kpsB, featuresB) = self.detectAndDescribe(imageb)

        # 匹配两张图片的所有特征点,返回匹配结果
        M = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)

拼接过程会用到加权融合去除图像拼接缝,先通过在warpPerspective image的图像坐标,

def get_transform_corners(imageA,H):
    corners_orig = np.array([[0, 0, imageA.shape[0], imageA.shape[0]],
                             [0, imageA.shape[1], 0, imageA.shape[1]],
                             [1, 1, 1, 1]])
    transform_corners = np.matmul(H, corners_orig)
    return transform_corners
#加权融合去接缝
def removal_seam_updown(img_trans, img_targ, transform_corners, threshold=20):
    # img_trans warpPerspective image
    # img_targ target image
    # transform_corners the 4 corners of warpPerspective image
    # corners_orig = np.array([[0, 0, 1],
    #                         [0, img.shape[0], 1],
    #                         [img.shape[1], 0, 1],
    #                         [img.shape[1], img.shape[0], 1]])
    # obtain 4 corners from T transform
    pano = copy.deepcopy(img_trans)
    pano[0:img_targ.shape[0], 0:img_targ.shape[1]] = img_targ
    y_down = img_targ.shape[1]
    y_top = int(min(transform_corners[1, 0], transform_corners[1, 1]))
    cols=pano.shape[1]
    # calculate weight matrix
    alphas = np.array([y_down - np.arange(y_top, y_down)]*cols) / (y_down - y_top)
    alphas=alphas.T
    alpha_matrix = np.ones((alphas.shape[0], alphas.shape[1], 3))
    alpha_matrix[:, :, 0] = alphas
    alpha_matrix[:, :, 1] = alphas
    alpha_matrix[:, :, 2] = alphas
    # common area one image no pixels
    alpha_matrix[img_trans[y_top:y_down, 0:cols, :] <= threshold] = 1
    img_targ = pano[:, 0:img_targ.shape[1]
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用OpenCV库中的sift算法进行特征点提取,然后使用加权平均融合算法将多张图像拼接全景图像。以下是Python代码示例: ```python import cv2 import numpy as np # 读取多张图像 img1 = cv2.imread('img1.jpg') img2 = cv2.imread('img2.jpg') img3 = cv2.imread('img3.jpg') # 使用sift算法进行特征点提取 sift = cv2.xfeatures2d.SIFT_create() kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) kp3, des3 = sift.detectAndCompute(img3, None) # 使用FLANN匹配器进行特征点匹配 FLANN_INDEX_KDTREE = 0 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) search_params = dict(checks=50) flann = cv2.FlannBasedMatcher(index_params, search_params) matches1 = flann.knnMatch(des1, des2, k=2) matches2 = flann.knnMatch(des2, des3, k=2) # 进行筛选,保留好的匹配点 good_matches1 = [] good_matches2 = [] for m, n in matches1: if m.distance < 0.7 * n.distance: good_matches1.append(m) for m, n in matches2: if m.distance < 0.7 * n.distance: good_matches2.append(m) # 计算单应性矩阵 src_pts1 = np.float32([kp1[m.queryIdx].pt for m in good_matches1]).reshape(-1, 1, 2) dst_pts1 = np.float32([kp2[m.trainIdx].pt for m in good_matches1]).reshape(-1, 1, 2) src_pts2 = np.float32([kp2[m.queryIdx].pt for m in good_matches2]).reshape(-1, 1, 2) dst_pts2 = np.float32([kp3[m.trainIdx].pt for m in good_matches2]).reshape(-1, 1, 2) H1, _ = cv2.findHomography(src_pts1, dst_pts1, cv2.RANSAC, 5.0) H2, _ = cv2.findHomography(src_pts2, dst_pts2, cv2.RANSAC, 5.0) # 计算拼接图像的大小 h1, w1 = img1.shape[:2] h2, w2 = img2.shape[:2] h3, w3 = img3.shape[:2] pts1 = np.float32([[0, 0], [0, h1], [w1, h1], [w1, 0]]).reshape(-1, 1, 2) pts2 = np.float32([[0, 0], [0, h2], [w2, h2], [w2, 0]]).reshape(-1, 1, 2) pts3 = np.float32([[0, 0], [0, h3], [w3, h3], [w3, 0]]).reshape(-1, 1, 2) dst1 = cv2.perspectiveTransform(pts1, H1) dst2 = cv2.perspectiveTransform(pts2, np.dot(H1, H2)) dst3 = cv2.perspectiveTransform(pts3, np.dot(np.dot(H1, H2), H2)) # 将多张图像拼接全景图像 max_x = int(max(dst1[1][0][0], dst1[2][0][0], dst2[1][0][0], dst2[2][0][0], dst3[1][0][0], dst3[2][0][0])) max_y = int(max(dst1[2][0][1], dst2[2][0][1], dst3[2][0][1])) min_x = int(min(dst1[0][0][0], dst2[0][0][0], dst3[0][0][0])) min_y = int(min(dst1[0][0][1], dst2[0][0][1], dst3[0][0][1])) shift_x = -min_x shift_y = -min_y h = max_y - min_y w = max_x - min_x result = np.zeros((h, w, 3), np.uint8) result[shift_y:shift_y + h1, shift_x:shift_x + w1] = img1 result[shift_y:shift_y + h2, shift_x:shift_x + w2] = cv2.warpPerspective(img2, H1, (w, h)) result[shift_y:shift_y + h3, shift_x:shift_x + w3] = cv2.warpPerspective(img3, np.dot(H1, H2), (w, h)) # 显示全景图像 cv2.imshow('result', result) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这段代码实现了sift算法进行特征点提取,FLANN匹配器进行特征点匹配,加权平均融合算法进行图像拼接,最终得到全景图像
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值