c++实现des算法_实现图像拼接,OpenCV就够了

07720abc54563b649ad1e063bc6cb0f6.png

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
fc3e6c7c0a44b1c868605c689f77e77f.png

图像中的圆圈就是 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 矩阵。 不同视角的图像上的点具有如下关系:

51916139ee25f1c089cfb3a965dc2402.png

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

462cb67829bae38ded8850f0171484fc.png

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

4. RANSAC 算法

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

c8ab640d3bffa2627765a5bedf31887d.png

算法步骤如下:

  • 在数据中随机的选择几个点设定为内点
  • 用内点拟合出一个模型
  • 把除内点以外的点(外点)代入我们拟合的模型中,如果计算得到的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

结果如下:

3ac9445714545c067c4a7a0f00b806b1.png

输入图像1

27612f8e00fe75666e1e84fd8fec78e1.png

输入图像2

52ddbad60abca167d13211d6cbbd1ce6.png

拼接图像

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值