RANSAC是“RANdom SAmple Consensus(随机抽样一致)”的缩写。它可以从一组包含“局外点”的观测数据集中,通过迭代方式估计数学模型的参数。它是一种不确定的算法——它有一定的概率得出一个合理的结果;为了提高概率必须提高迭代次数。
(1)数据由“局内点”组成,例如:数据的分布可以用一些模型参数来解释;
(2)“局外点”是不能适应该模型的数据;
(3)除此之外的数据属于噪声。
局外点产生的原因有:噪声的极值;错误的测量方法;对数据的错误假设。
RANSAC也做了以下假设:给定一组(通常很小的)局内点,存在一个可以估计模型参数的过程;而该模型能够解释或者适用于局内点
1. 随机选择四对匹配特征
2. 根据DLT计算单应矩阵 H (唯一解)
3. 对所有匹配点, 计算映射误差ε= ||pi’, H pi||
4. 根据误差阈值, 确定inliers(例如3-5像素)
5. 针对最大inliers集合, 重新计算单应矩阵 H
直线拟合
• 给定若干二维空间中的点, 求直线 y=ax+b ,
使得该直线对空间点的拟合误差最小。
• 随机选择两个点
• 根据该点构造直线
• 给定阈值, 计算inliers数量
• 随机选择两个点
• 根据该点构造直线
• 给定阈值, 计算inliers数量
• 随机选择两个点
• 根据该点构造直线
• 给定阈值, 计算inliers数量
• 随机选择两个点
• 根据该点构造直线
• 给定阈值, 计算inliers数量
图像拼接实例:
from pylab import *
from numpy import *
from PIL import Image
# If you have PCV installed, these imports should work
from PCV.geometry import homography, warp
from PCV.localdescriptors import sift
"""
This is the panorama example from section 3.3.
"""
# set paths to data folder
featname = ['./image/'+str(i+1)+'.sift' for i in range(2)]
imname = ['./image/'+str(i+1)+'.jpg' for i in range(2)]
# extract features and match
l = {}
d = {}
for i in range(2):
sift.process_image(imname[i],featname[i])
l[i],d[i] = sift.read_features_from_file(featname[i])
matches = {}
for i in range(1):
matches[i] = sift.match(d[i+1],d[i])
# visualize the matches (Figure 3-11 in the book)
for i in range(1):
im1 = array(Image.open(imname[i]))
im2 = array(Image.open(imname[i+1]))
figure()
sift.plot_matches(im2,im1,l[i+1],l[i],matches[i],show_below=True)
# function to convert the matches to hom. points
def convert_points(j):
ndx = matches[j].nonzero()[0]
fp = homography.make_homog(l[j+1][ndx,:2].T)
ndx2 = [int(matches[j][i]) for i in ndx]
tp = homography.make_homog(l[j][ndx2,:2].T)
# switch x and y - TODO this should move elsewhere
fp = vstack([fp[1],fp[0],fp[2]])
tp = vstack([tp[1],tp[0],tp[2]])
return fp,tp
# estimate the homographies
model = homography.RansacModel()
fp,tp = convert_points(0)
H_01 = homography.H_from_ransac(fp,tp,model)[0] #im 0 to 1
# warp the images
delta = 2000 # for padding and translation
im1 = array(Image.open(imname[0]), "uint8")
im2 = array(Image.open(imname[1]), "uint8")
im_12 = warp.panorama(H_01,im1,im2,delta,delta)
figure()
imshow(array(im_12, "uint8"))
axis('off')
savefig("example1.png",dpi=300)
show()
光照良好:
总体上效果还好 但在有些细节方面还是出现问题 比如门的上边。
在光照偏暗条件下:
识别效果稍差 匹配的点明显减少
在黑暗的条件下 识别不出来
参考:https://blog.csdn.net/robinhjwy/article/details/79174914