Automatic Panoramic Image Stitching using Invariant Features笔记

第一次接触全景图像的拼接,先简单的来做个论文笔记。
简单来说,全景图像拼接过程可以简述为:寻找所有图像重叠区域鲁棒的特征点,根据图像特征点匹配得到不同图像间的单应性矩阵,以某个图像为基准图像(k-d tree 得到),将其余图像拼接到这幅图中,然后通过图像融合得到最终结果。当然这中间还有一些其他的问题,在后面在赘述。
该篇论文最终算法为:
在这里插入图片描述

在这里我将按照论文最终算法步骤来介绍整篇论文内容,而非原文中的顺序:

  1. 提取图像中的sift特征点;

  2. 进行sift特征点的匹配,对于图像A中的某个特征,可以利用K-NN算法在另一幅图中寻找K个最近的特征点,然后将K个特征点进行比较,从而判断是否找到了匹配点,在寻找K个最近的特征点时,k-d tree是一个很有效的算法 (这里的k和KNN的K不同)。

  3. 由于不是每幅图和所有的图都是可以拼接的,因此这里对于每幅图选择m个候选图像(有最大匹配点数量的),接下来要根据匹配的特征点求解两幅图像之间的变换矩阵:
    论文中变换矩阵建模即在Feature Matching部分
    在这里插入图片描述

    参考相机成像模型,考虑相机是围绕中心只做了旋转而没有做平移(或者考虑物体离相机足够远),很容易得到
    在这里插入图片描述
    其中,旋转矩阵我们一般是通过三个角度来描述,这里采用的是指数形式便于运算即:
    在这里插入图片描述
    这里论文还把上面的过程简化为了一个仿射变换(实际上应该更倾向于射影变换),自由度为6,该变换模型需要在RANSAC部分需要使用,

在这里插入图片描述
射影变换公式,自由度为8:
(1) H = [ h 11 h 12 h 13 h 21 h 22 h 23 h 31 h 32 1 ] H = \left[ \begin{matrix} h_{11} & h_{12} & h_{13} \\ h_{21} & h_{22}& h_{23}\\ h_{31}& h_{32} & 1 \end{matrix} \right] \tag{1} H=h11h21h31h12h22h32h13h231(1)

  1. 为了计算射影变换的参数值,显然只需要四个点,由于得到的匹配点中点数显然多于四个为了,提高计算精度,可以使用最小二乘法;此时有一个问题为得到的匹配点对中有内点和外点,内点数量越多,可以得到更为准确的结果,如何区分内点和外点,即RANSAC算法:
    抽n次中至少有一次匹配点为正确的概率为:
    p ( H i s c o r r e c t ) = ( 1 − ( 1 − p i r ) n p(H is correct)=(1 - (1-p_{i}^{r})^n p(Hiscorrect)=(1(1pir)n--------------------------(2)
    这里 p i p_{i} pi是内点概率, r r r代表每次抽出点的数量,这里为4。
    从(1)中可以推导出:
    n = l o g p l o g ( 1 − ( 1 − p i r ) n = \frac{log p}{log(1 - (1-p_{i}^{r})} n=log(1(1pir)logp--------------------------(3)
    那么RANSAC算法基本步骤为
  • 初始化p, 内点的阈值 η \eta η 迭代次数N
  • 进入迭代
    1) 随机选取4个匹配点对,要求三个不能共线
    2)根据公式(1)计算H
    3)对所有的匹配点对:计算重投影误差: d = ∣ ∣ u i − H u j ∣ ∣ d = ||u_{i} - Hu_{j}|| d=uiHuj,如果误差小于阈值 η \eta η,则为内点,反之则为外点;
    4)根据3)即可计算出内点概率 p i p_{i} pi,进而通过公式(3)更新迭代次数N
    *由迭代循环内最大的内点数计算投影矩阵H
  1. 进一步验证候选图像是否需要拼接:
    n i > α + β n f n_{i}>\alpha+\beta n_{f} ni>α+βnf
    这里 n i n_{i} ni是内点数, n f n_{f} nf为匹配点数量, α \alpha α β \beta β为实验参数,论文给的为8.0,3.0满足该条件即认为两幅图有较好的匹配关系,需要拼接;

  2. 尽管通过RANSAC方法已经初步计算出了单应性矩阵,但是上面方法是孤立的处理图片,没有考虑到多幅图像的空间一致性,也会造成错误的累积,因此这里采用光束平差法(Bundle Adjustment)处理所有的图像,得到更为准确的单应性矩阵,这里定义的误差不是前面标准的欧氏距离,而是Huber robust error function
    在这里插入图片描述
    在这里插入图片描述
    绿色代表 σ = 1 \sigma=1 σ=1的Huber robust error, 蓝色代表平法误差,Huber robust error function好处在于当误差很大时为线性,一些误差很大的异常点的影响较小。
    求解时采用Levenberg-Marquardt方法,迭代因子为:
    在这里插入图片描述
    解析解通过链式法则来求,这部分的数学计算我还不是特别懂。

  3. Panorama Straightening,直接拼接起来的图像会有明显的波纹,如图需要将其校正为水平方向:
    在这里插入图片描述

  4. Gain Compensation,如果不同图片曝光程度不同,那么在拼接时候就会有明显的痕迹,因此需要对其进行曝光补偿。
    在这里插入图片描述
    其中 R ( i , j ) R(i, j) R(i,j)代表的是重合区域, I ( u i ) I(u_{i}) I(ui)使用重叠区域的平均值来代替。
    在这里插入图片描述
    这样显然 g = 0 g=0 g=0即是最优解,但显然不是我们想要的结果,因而论文中加了一个prior term。该公式可以通过求导得到闭式解。
    在这里插入图片描述

  5. Multi-Band Blending 多频段融合,论文中给出的说法略复杂,可以参照这篇博客
    首先分别建立各个图像的拉普拉斯金字塔,然后针对重叠区域,把它们的金字塔的相同层 应用 I = ∑ i = 1 n I i ∗ w i ∑ i = 1 n w i I = \frac{\sum_{i=1}^{n} I^{i}*w^{i}}{\sum_{i=1}^{n}w^{i}} I=i=1nwii=1nIiwi进行合并,最后对该合并后的金字塔进行逆拉普拉斯变换,从而得到最终的融合图像
    构建Laplace金字塔: L n = G n − e x p a n d ( G n + 1 ) L_{n} = G_{n} - expand(G_{n+1}) Ln=Gnexpand(Gn+1), L G代表Laplace变换和Gaussian模糊;
    在这里插入图片描述
    构建融合图像:
    S n = R n + e x p a n d ( S n + 1 ) S_{n}=R_{n}+expand(S_{n+1}) Sn=Rn+expand(Sn+1), 其中 R n R_{n} Rn为合成金字塔,这里采用公式 I = ∑ i = 1 n I i ∗ w i ∑ i = 1 n w i I = \frac{\sum_{i=1}^{n} I^{i}*w^{i}}{\sum_{i=1}^{n}w^{i}} I=i=1nwii=1nIiwi进行合成;S_{n}为融合金字塔
    在这里插入图片描述
    在这里插入图片描述
    参考博客1
    参考博客2
    参考文章:Automatic Panoramic Image Stitching using Invariant Features

Panoramic stitching is the process of combining multiple images to create a single panoramic image. Optical flow tracing is a technique used to track the movement of pixels between consecutive frames in a video or between multiple images. Here's an example of how you can implement panoramic stitching using the optical flow tracing principle in Python: 1. Start by importing the necessary libraries, such as OpenCV, Numpy, and Matplotlib. ``` import cv2 import numpy as np import matplotlib.pyplot as plt ``` 2. Load the images that you want to stitch into a list. ``` images = [cv2.imread('image1.jpg'), cv2.imread('image2.jpg'), ... ] ``` 3. Use the Lucas-Kanade optical flow method to track the movement of pixels between the images. ``` gray_images = [cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) for img in images] prev_gray = gray_images[0] flow = None for i in range(1, len(gray_images)): curr_gray = gray_images[i] flow = cv2.calcOpticalFlowFarneback(prev_gray, curr_gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0) prev_gray = curr_gray ``` 4. Use the optical flow information to warp the images and align them. ``` warped_images = [] for i in range(len(images)): H = np.eye(3) for j in range(i): H = np.dot(H, cv2.estimateRigidTransform(gray_images[j], gray_images[i], False)) warped = cv2.warpPerspective(images[i], H, (images[i].shape[1] + int(H[0,2]), images[i].shape[0] + int(H[1,2]))) warped_images.append(warped) ``` 5. Finally, use the aligned images to create a single panoramic image. ``` panorama = warped_images[0] for i in range(1, len(warped_images)): panorama = cv2.addWeighted(panorama, 1, warped_images[i], 1, 0) ``` This is just a basic example, and you may need to adjust the parameters or use a different approach depending on your specific use case. But I hope it gives you an idea of how to implement panoramic stitching using the optical flow tracing principle in Python.
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值