美文网首页OpenCV Vision
图像处理实战-图像拼接

图像处理实战-图像拼接

作者: YvanYan | 来源:发表于2020-08-19 11:05 被阅读0次

    图像拼接是将两张具有相同信息的图片,根据相同的信息拼接起来,从而得到全景图片。

    完整代码:
    https://github.com/YvanYan/image_processing/tree/master/image_stitching

    步骤:
    1.输入需要拼接的图像
    2.查找图片中的特征点和特征描述
    3.匹配两张图片所有的特征点
    4.进行视角变换,拼接


    1.输入图像

    图像A 图像B

    根据这两张图片中相同区域进行匹配拼接。

    2.查找图片中的特征点和特征描述

        def find_kps_feas(self, image):
            # 建立SIFT生成器
            descriptor = cv2.xfeatures2d.SIFT_create()
            # 检测SIFT特征点
            (kps, features) = descriptor.detectAndCompute(image, None)
    
            npkps = np.float32([kp.pt for kp in kps])
    
            # 返回特征点集
            return (kps, npkps, features)
    

    使用SIFT算法来检测特征点,关于SIFT网上有许多讲解,在此不在解释。(这篇博客讲解的很好,https://blog.csdn.net/qq_37374643/article/details/88606351)。使用SIFT_create来实例化SIFT。detectAndCompute来检测图片中的特征点(kps)和特征描述(features)。这里npkps是为了计算方便将kps转成了numpy,原始的kps在后面绘图的时候会用到。

    3.匹配两张图片所有的特征点

        def matchKeypoints(self, kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh):
            bf = cv2.BFMatcher()
            allMatches = bf.knnMatch(featuresB, featuresA, k=2)
            matches = []
            good = []
            for m, n in allMatches:
                if m.distance < ratio * n.distance:
                    matches.append((m.trainIdx, m.queryIdx))
                    good.append([m])
    
            if len(matches) > 4:
                ptsA = np.float32([kpsA[i] for (i, _) in matches])
                ptsB = np.float32([kpsB[i] for (_, i) in matches])
    
                (H, status) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC, reprojThresh)
    
            return (good, H, status)
    

    matchKeypoints函数的输入分为图像A和kpsA图像B和kpsBratio是David Lowe’s ratio测试变量、reprojThresh是RANSAC重投影门限。
    cv2.BFMatcher建立暴力匹配器。使用knnMatch进行匹配,通过ratio过滤掉不符合条件的特征匹配对。queryIdx:测试图像的特征点描述符的下标(第几个特征点描述符),同时也是描述符对应特征点的下标。trainIdx:样本图像的特征点描述符下标,同时也是描述符对应特征点的下标。findHomography: 计算多个二维点对之间的最优单映射变换矩阵 H(3行x3列) ,使用最小均方误差或者RANSAC方法。因为变换矩阵H是3 * 3,且H[3][3]设为1,所以共有八个未知数,因此需要保证至少有四组匹配值。
    在匹配过程中要注意顺序,例如本代码中knnMatch输入是(图像B,图像A),那么trainIdx代表的是图像A的下标,queryIdx代表的图像B的下标。在findHomography时,我们是将图像B图像A进行变换,因此输入顺序是(ptsB,ptsA)。

    变换后的图像B

    4.进行视角变换,拼接

            M = self.matchKeypoints(npkpsA, npkpsB, feasA, feasB, ratio, reprojThresh)
            (good, H, status) = M
            result = cv2.warpPerspective(imageB, H, (imageA.shape[1] + imageB.shape[1], imageB.shape[0]))
            self.cv_show('result1', result)
            result[0:imageA.shape[0], 0:imageA.shape[1]] = imageA
            self.cv_show('result2', result)
    
            img = cv2.drawMatchesKnn(imageB, kpsB, imageA, kpsA, good, None, flags=2)
            self.cv_show('result', img)
    

    warpPerspective根据变化矩阵H将图像B进行视角变换。然后将图像A拼接到相应位置。drawMatchesKnn是将两个图像的特征匹配信息绘制出来。

    拼接结果图片 特征匹配图

    在进行实现过程中,我想将图像A进行视角变化,变换至图像B的大小,然后将图像B拼接到图像A上。但是未能实现,图像A视角变换后,会将图片信息丢失一部分。希望有大神可以指导一下。

    相关文章

      网友评论

        本文标题:图像处理实战-图像拼接

        本文链接:https://www.haomeiwen.com/subject/tofljktx.html