龙空技术网

实现图像拼接,OpenCV就够了

唐进民 786

前言:

现在我们对“sift算法图像融合”大体比较看重,小伙伴们都需要剖析一些“sift算法图像融合”的相关资讯。那么小编在网络上网罗了一些有关“sift算法图像融合””的相关资讯,希望同学们能喜欢,姐妹们一起来了解一下吧!

Image Stitching (图像拼接)是一个非常有用的技术,本文将基于 OpenCV 对其进行实现,Image Stitching 的步骤可以大致分为如下几个部分:

获取两张输入的图像中关键点和局部不变性描述符,这里使用 SIFT 算法完成匹配两张输入图像的局部不变性描述符使用 RANSAC 算法基于我们匹配的特征向量合成 Homography 矩阵使用第三步得到的 Homography 矩阵对图像进行拼接1. SIFT特征点和特征描述提取

SIFT 算法广泛使用在计算机视觉领域,我们可以直接调用 OpenCV 中已经实现了的库来完成SIFT 算法,代码如下:

import cv2 def sift_kp_des(img): sift = cv2.xfeatures2d_SIFT.create() kp, des = sift.detectAndCompute(img, None) kp_img = cv2.drawKeypoints(img, kp, None) return kp_img, kp, des

图像中的圆圈就是 SIFT算法检测出的关键点。

2. 特征点匹配

SIFT 算法得到了图像中的特征点以及相应的特征描述,接下来就可以使用K近邻算法求取在空间中距离最近的K个数据点,并将这些数据点归为一类。

在进行特征点匹配时,使用KNN算法找到最近邻的两个数据点,如果这两个点的距离比值小于一个我们指定的值,那么我们就可以认为这两个点是最接近的,并认为这两个点是好的匹配点加入到我们的列表中。实现代码如下:

def get_good_match(des1,des2): bf = cv2.BFMatcher() maches = bf.knnMatch(des1, des2, k=2) good_kp = [] for (i,j) in maches: if i.distance < 0.75*j.distance: good_kp.append(i) return good_kp
3. 生成 Homography 矩阵

通过上面的步骤,我们找到了许多的匹配点,但是要完成图像的拼接还需要用到 Homography 矩阵。 不同视角的图像上的点具有如下关系:

其中[x1,y1 ,1]和[x2,y2,1]分别表示两张图像对应像素的齐次坐标。Homography 矩阵就是下面这个矩阵:

一般设 h22 为 1,所以 Homography 矩阵只有八个未知参数,要求解这八个未知参数只需要四个像素点即可。

4. RANSAC 算法

我们的匹配点非常的多,那么要如何挑出最合适的四个点,来求得最优的 Homography 矩阵。这个过程要用到 RANSAC 算法(Random Sample Consensus,随机抽样一致算法),它能够有效的去除误差很大的点,并且这些点不计入模型的计算之中。过程图像如下:

算法步骤如下:

在数据中随机的选择几个点设定为内点用内点拟合出一个模型把除内点以外的点(外点)代入我们拟合的模型中,如果计算得到的Loss在指定的阈值子内,就将这些点标记为内点如果此时内点的数量足够多的话,可以认为这个模型比较理想了,那么就可以用现有的内点重新拟合出一个更好的模型,否则重复以上步骤,最后得到最理想的模型。5. 拼接

基于第三和第四部分进行图像拼接,代码如下:

def siftImage(img_1,img_2):  kp_img_1, kp_1, des_1 = sift_kp_des(img_1) kp_img_2, kp_2, des_2 = sift_kp_des(img_2) good_kp = get_good_match(des_1, des_2)  if len(good_kp) > 4: ptsA= np.float32([kp_1[m.queryIdx].pt for m in good_kp]).reshape(-1, 1, 2) ptsB = np.float32([kp_2[m.trainIdx].pt for m in good_kp]).reshape(-1, 1, 2) ransacReprojThreshold = 4  H, status =cv2.findHomography(ptsA,ptsB,cv2.RANSAC,ransacReprojThreshold) imgOutput = cv2.warpPerspective(img_1, H, (img_1.shape[1]+img_2.shape[1], img_1.shape[0])) imgOutput[0:img_2.shape[0], 0:img_2.shape[1]] = img_2  return imgOutput

结果如下:

输入图像1

输入图像2

拼接图像

其中第一张和第二张是输入的原图像,最后一张是我们利用 SIFT 算法和 RANSAC 算法拼接出来的的图像。

标签: #sift算法图像融合 #图像拼接算法 #opencv实现图像拼接 #sift算法拼接