赞
踩
RANSAC是“RANdom SAmple Consensus(随机抽样一致)”的缩写。它可以从一组包含“局外点”的观测数据集中,通过迭代方式估计数学模型的参数。它是一种不确定的算法——它有一定的概率得出一个合理的结果;为了提高概率必须提高迭代次数。
RANSAC的基本假设是:
(1)数据由“局内点”组成,例如:数据的分布可以用一些模型参数来解释;
(2)“局外点”是不能适应该模型的数据;
(3)除此之外的数据属于噪声。
局外点产生的原因有:噪声的极值;错误的测量方法;对数据的错误假设。
RANSAC也做了以下假设:给定一组(通常很小的)局内点,存在一个可以估计模型参数的过程;而该模型能够解释或者适用于局内点。
RANSAC算法的输入是一组观测数据,一个可以解释或者适应于观测数据的参数化模型,一些可信的参数。
RANSAC通过反复选择数据中的一组随机子集来达成目标。被选取的子集被假设为局内点,并用下述方法进行验证:
1.首先我们先随机假设一小组局内点为初始值。然后用此局内点拟合一个模型,此模型适应于假设的局内点,所有的未知参数都能从假设的局内点计算得出。
2.用1中得到的模型去测试所有的其它数据,如果某个点适用于估计的模型,认为它也是局内点,将局内点扩充。
3.如果有足够多的点被归类为假设的局内点,那么估计的模型就足够合理。
4.然后,用所有假设的局内点去重新估计模型,因为此模型仅仅是在初始的假设的局内点估计的,后续有扩充后,需要更新。
5.最后,通过估计局内点与模型的错误率来评估模型。
整个这个过程为迭代一次,此过程被重复执行固定的次数,每次产生的模型有两个结局:
1、要么因为局内点太少,还不如上一次的模型,而被舍弃,
2、要么因为比现有的模型更好而被选用。
RANSAC loop:
1.随机选择四对匹配特征
2.根据DLT计算单应矩阵 H (唯一解)
3 .对所有匹配点,计算映射误差
ε
=
∥
p
i
′
,
H
p
i
∥
\varepsilon = \left \|{p_i'} ,H{p_i} \right \|
ε=∥pi′,Hpi∥
4.根据误差阈值,确定inliers(例如3-5像素)
5.针对最大inliers集合,重新计算单应矩阵 H
1.基于ransac的sift匹配
python3.6+opencv3.3
转自 推杯问盏
import cv2 import numpy as np def sift_kp(image): gray_image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) sift=cv2.xfeatures2d.SIFT_create() kp,des = sift.detectAndCompute(image,None) kp_image = cv2.drawKeypoints(gray_image,kp,None) return kp_image,kp,des def get_good_match(des1,des2): bf = cv2.BFMatcher() matches = bf.knnMatch(des1, des2, k=2) #des1为模板图,des2为匹配图 matches = sorted(matches,key=lambda x:x[0].distance/x[1].distance) good = [] for m, n in matches: if m.distance < 0.75 * n.distance: good.append(m) return good def siftImageAlignment(img1,img2): _,kp1,des1 = sift_kp(img1) _,kp2,des2 = sift_kp(img2) goodMatch = get_good_match(des1,des2) if len(goodMatch) > 4: ptsA= np.float32([kp1[m.queryIdx].pt for m in goodMatch]).reshape(-1, 1, 2) ptsB = np.float32([kp2[m.trainIdx].pt for m in goodMatch]).reshape(-1, 1, 2) ransacReprojThreshold = 4 H, status =cv2.findHomography(ptsA,ptsB,cv2.RANSAC,ransacReprojThreshold); imgOut = cv2.warpPerspective(img2, H, (img1.shape[1],img1.shape[0]),flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP) return imgOut,H,status img1 = cv2.imread(r'sift_img/8.png') img2 = cv2.imread(r'sift_img/7.png') _,kp1,des1 = sift_kp(img1) _,kp2,des2 = sift_kp(img2) goodMatch = get_good_match(des1,des2) img3 = cv2.drawMatches(img1, kp1, img2, kp2, goodMatch[:5], None, flags=2) #----or---- #goodMatch = np.expand_dims(goodMatch,1) #img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, goodMatch[:5], None, flags=2) cv2.imshow('img',img3) cv2.waitKey(0) cv2.destroyAllWindows()
2.基于ransac的harris匹配
#coding=utf-8 import numpy as np import harris import ransac from PIL import Image from pylab import * import matplotlib.pyplot as plt import win_unicode_console win_unicode_console.enable() img1 = np.array(Image.open('D:/ck/6.jpg').convert('L')) img2 = np.array(Image.open('D:/ck/10.jpg').convert('L')) wid = 9 harrisimg_1 = harris.compute_harris_response(img1) #计算Harris响应 filtered_coords_1 = harris.get_harris_points(harrisimg_1) #获取Harris角点的坐标 harris.plot_harris_points(img1, filtered_coords_1) #在图像中绘制Harris角点的位置 d1 = harris.get_descriptors(img1,filtered_coords_1,wid) #获取Harris角点的描述子 harrisimg_2 = harris.compute_harris_response(img2) filtered_coords_2 = harris.get_harris_points(harrisimg_2) harris.plot_harris_points(img2, filtered_coords_2) d2 = harris.get_descriptors(img2,filtered_coords_2,wid) print('strating matching') match_points_coords_1 = [] match_points_coords_2 = [] matches = harris.match(d1,d2) #获取匹配关系,这个函数得到的匹配精度不太好。如果想获得更加精确些的匹配,可以调用harris.match_twosided(d1,d2) ###获取匹配点 for i,m in enumerate(matches): if m > 0: match_points_coords_1.append(filtered_coords_1[i]) match_points_coords_2.append(filtered_coords_2[m]) points_1 = np.array(match_points_coords_1).T points_2 = np.array(match_points_coords_2).T X = np.concatenate([points_1,np.ones([1,points_1.shape[1]])]) Y = np.concatenate([points_2,np.ones([1,points_2.shape[1]])]) ###利用这些匹配点计算两个图的单应矩阵 H,X_,Y_ = ransac.homography(X,Y,10) print(H) ###绘制在图片上的原始匹配 plt.figure() plt.gray() harris.plot_matches(img1,img2,filtered_coords_1,filtered_coords_2,matches) show() img3 = harris.appendimages(img1,img2) img3 = np.vstack((img3,img3)) #np.vstack()是垂直地把数组拼接在一起 imshow(img3) ###绘制经过优化后的匹配 for i in range(X_.shape[1]): plot([X_[1][i],Y_[1][i]+img1.shape[1]],[X_[0][i],Y_[0][i]],'r') axis('off') show()
1.数据集
(前四个为景深丰富,后五个为景深单一)
本次实验我选用图1 5作为景深丰富,图6 10作为景深单一
因为sift的精度较高看实验现象不够明显,所以我多使用了harris角点检测来作为实验。
(1)景深丰富组
左图为sift匹配效果,右图为harris匹配效果
基于ransac算法的harris
基于ransac算法的sift
(2)景深单一组
左图为sift匹配效果,右图为harris算法效果
基于ransac算法的harris
基于ransac算法的sift
分析:RANSAC算法智能描述同一平面的问题,当图片处于不同平面时,非常容易出错,在harris匹配前提下,以上经过筛选的几条,基本上都出错了。而在sift特征匹配算法中,除了第一组图片景深高,因为处于不同平面匹配效果很差,连RANSAC优化以后都没有找出以外,景深单一组的sift算法匹配正确率高,优化效果也好。之所以没有把全部数据集的效果都放出来,是因为数据集中其他的sift匹配效果也并不好,不是匹配错就是没有匹配,应该是我数据集采集得不好。
RANSAC的优点是它能鲁棒的估计模型参数。例如,它能从包含大量局外点的数据集中估计出高精度的参数。
RANSAC的缺点是它计算参数的迭代次数没有上限;如果设置迭代次数的上限,得到的结果可能不是最优的结果,甚至可能得到错误的结果。
RANSAC只有一定的概率得到可信的模型,概率与迭代次数成正比。RANSAC的另一个缺点是它要求设置跟问题相关的阀值。
RANSAC算法因为需要进行大量的迭代计算和数据处理,因此在某些复杂场景的拼接过程中,效率会比较低下。在本次实验可以看出优化的效果并不是很好,因为一开始给的匹配就不太好,如果匹配精度比较好的话,优化的结果应该会更好一点。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。