赞
踩
资源下载地址:https://download.csdn.net/download/sheziqiong/85824219
资源下载地址:https://download.csdn.net/download/sheziqiong/85824219
Harris 角点检测算子是于 1988 年由 Chris Harris & Mike Stephens 提出来的角点检测方法,实质上是对 Moravec 算子的改良和优化。算法基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。
当窗口发生移动时,滑动前与滑动后对应的窗口中的像素点灰度变化描述如下:
即:
其中:
所以 E 可表示为:
由于采用了正方形窗口,E 的响应比较容易受到干扰,所以要对 E 做一次高斯平滑增加抗噪能力。接着将 E 变为二次型:
然后 Harris 定义了一个角点响应函数:
至此,可以求得每个点的角点响应值。然后用阈值过滤掉一部分的角点,再用非极大值抑制进行细化,即可得到图像的角点。
harris_corners.m
image:需要检测角点的(HW3)图像。
window_size:检测窗口的大小。
k:角点响应方程参数。
border:我们对图像边界上的角点并不感兴趣,忽略边界的角点。
corners:检测出的角点结果。(H*W)的 0/1 值图像,认为是角点处的值置为 1,不是的置为 0。
8.输出结果。
具体实现请见 Matlab 代码及代码注释。
当检测窗口大小取 3*3,参数 k 取 0.04,边界 border 取 10 像素时,对于图像 sudoku.png 能检测出 1249 个角点,耗时大约在 0.3-0.5 秒之间,如图所示。
利用 Harris 角点检测算法定位两张图片中的关键点后,接下来需要对检测到的关键点进行匹配,确定好两张图片中哪些点是一一对应的。这就需要先对关键点进行描述。一个简单的方法是,选取关键点周围的一个固定区域(patch),并利用该区域的信息生成一组描述向量(descriptors)。由于用于测试的两张实例比较简单,可以直接用像素值当描述向量(即展开成一维向量)。为了增加光照稳定性,需要将这个向量进行标准正态化。
describe_keypoints.m
simple_descriptor.m
describe_keypoints.m 输入:
image:(HW3)图像,用于提取 patch 中的像素值,生成描述向量。
corners:(H*W)图像,Harris 角点检测函数 harris_corners( )检测出的角点图。
patch_size:patch 的大小(patch_size*patch_size)。
describe_keypoints.m 输出:
keypoints:(m*2)矩阵,行数为角点索引,即第 i 行存储的内容(x,y)就是第 i 个角点在原图中的 x 坐标和 y 坐标。
descriptors:m*(patch_sizepatch_size)矩阵,行数为角点索引,即第 i 行存储的(1(patch_size*patch_size))数列就是第 i 个角点的描述子。
simple_descriptor.m
patch:(patch_size*patch_size)矩阵。
simple_descriptor.m
out:(1*(patch_size*patch_size))向量,展开后的标准正态化 patch。
4.输出描述子矩阵 descriptors。
具体实现请见 Matlab 代码及代码注释。
当检测窗口大小取 3*3,参数 k 取 0.04,边界 border 取 20 时,img1 和 img2 的 Harris 角点检测结果如图所示:
img1 能检出 1440 个角点,img2 能检出 1585 个角点,当 patch_size 取 16 时,每个角点拥有一个 1256 的描述子,img1 像素值特征描述 descriptors1 为(1440256)矩阵,img2 像素值特征描述 descriptors1 为(1585*256)矩阵,耗时大约在 0.05-0.1 秒之间。
原理简介:
得到了 descriptors1(1440256),descriptors2(1585256)后,需要根据这些描述子将角点进行匹配,即计算向量的相似性。向量相似性有多种方法进行度量,如欧氏距离,曼哈顿距离,切比雪夫距离等,这里的匹配策略可以使用特征向量的欧氏距离来作为两幅图像中关键点的相似性判定度量。
主要方法是:取 img1 中的某个关键点,并找出其与 img2 中欧氏距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离少于某个比例阈值,则接收这一对匹配点。
match_descriptors.m
descriptors1:m*d 描述子矩阵。
descriptors2:n*d 描述子矩阵。
k:比例阈值。
count:匹配上的角点对数。
matched_points:(count*2)矩阵,保存匹配上的角点的坐标。
具体实现请见 Matlab 代码及代码注释。当比例阈值 k 取 0.8(论文给的参数)时,在 img1 和 img2 中能匹配 327 对点,如图所示:
调整参数可以发现,降低比例阈值,匹配点数目会减少,但更加稳定。当把 k 调整为 0.7 时(PPT 老师给的参数),在 img1 和 img2 中能匹配 239 对点,匹配效果更好,如图所示:
k=0.8
k=0.7
原理简介:
经过匹配函数的计算,可以得到一组匹配点的对应坐标。仿射变换(Affine Transformation)是一种二维坐标到二维坐标之间的线性变换,保持二维图形的“平直性”和“平行性”,可以描述图像的平移、旋转、缩放效果。
设 img1 和 img2 中的一对匹配点为和,即需要计算一个矩阵使,仿射变换可以由多个基础平移、旋转、缩放矩阵复合而成,即的计算又可以写成:
对每个点的残差可以定义为:
损失函数可以定义为:
可以将仿射变换写成矩阵形式:
即
然后可以根据最小二乘法方程拟合出所需要的仿射变换矩阵。(这里用的是论文上的排列方式,在 PPT 上、矩阵有另一种排列方式,计算结果是相同的。)
fit_affine_matrix.m
x、y、u、v:角点坐标集,角点坐标集。
H:拟合的仿射变换矩阵。
需要注意的是,(x,y)应输入 img2 中匹配点的坐标,(u,v)应输入 img1 中匹配点的坐标,否则拟合出来的是 img1 变换成 img2 的变换矩阵。
具体实现请见 Matlab 代码及代码注释。
为了使后文的 RANSAC 算法效果看起来更明显,这里的变换矩阵是用比例阈值 k 取 0.8 时匹配出来的角点所拟合的。此时图像变换以及拼接结果如图所示:
直接求解仿射变换矩阵的结果并不是很理想,这是因为在确定对应点时,我们的限制条件并不算精确,导致引入了许多无效数据。我们可以利用 RANSAC 方法来进一步对数据进行筛选,求解变换矩阵。
RANSAC 是“RANdom SAmple Consensus(随机抽样一致)”的缩写。它可以从一组包含“外点”的观测数据集中,通过迭代方式估计数学模型的参数。它是一种不确定的算法——它有一定的概率得出一个合理的结果;为了提高概率必须提高迭代次数。
这里滤除误匹配对采用 RANSAC 算法寻找一个最佳变换矩阵 H,矩阵大小为 3×3。RANSAC 目的是找到最优的参数矩阵使得满足该矩阵的数据点个数最多。由于仿射变换矩阵有 6 个未知参数,至少需要 6 个线性方程求解,对应到点位置信息上,一组点对可以列出两个方程,则至少包含 3 组匹配点对。同理透视变换就需要找 4 对点。作业中的 RANSAC 的主要步骤包括了:
ransac.m
keypoints1:(m*2)img1 角点坐标索引矩阵。
keypoints2:(n*2)img2 角点坐标索引矩阵。
matched_points:(p*2)矩阵,保存匹配上的角点的坐标。
iterations:RANSAC 迭代次数。
thres:RANSAC 误差阈值。
num_inliers:取 num_inliers 对点估计模型。
ransac_matched_points:(q*2)矩阵,保存 RANSAC 方法剔除误匹配后的匹配点坐标。
count_inliers:RANSAC 方法剔除误匹配后的匹配点个数。
误差描述好像还有其他方法,例如计算前后两个矩阵的范数等,可以采取一些扩大误差的方法得到更精确的内点集合。RANSAC 迭代一定次数后计算结果不会变的更好。RANSAC 方法迭代 500 次,误差阈值取 0.003,比例阈值 k 取 0.8 时,一般会剔除 220 对左右的匹配点,效果如下:
匹配对比如下:
另外,关于取计算估计模型的随机点的对数也会对结果产生影响,前面是取 3 对点估算仿射变换矩阵模型的结果,而 3 对点只能刚好解算模型,一般不能发现粗差(即局外点),一般来讲,数据应该远大于 3 对,取 10 对点估计模型的结果如下,可以看到效果比取 3 对要好一些:
3 对点估计模型
10 对点估计模型
为了缩短 RANSAC 方法的计算时间,还可以输入一个“置信度”阈值,在计算过程中计算一个匹配错误率以衡量 RANSAC 估计出的模型(即我们的仿射变换矩阵)的好坏,如果这个模型已经足够令人满意,那么可以直接跳出循环并输出结果,而不用继续参加剩下的迭代。具体实现请见 Matlab 代码及代码注释。
在前面的生成描述向量函数中,直接用关键点周围的一个固定区域(patch)的经过标准正态化的像素值作为描述向量(即展开成一维向量)。在这一模块里将会利用 HOG 来描述特征点的特征。
HOG 即 Histogram Of Gradient(方向梯度直方图),梯度的方向分布将会被用作特征。计算方向梯度直方图的主要步骤是:
hog_descriptor.m
patch:(m*m)矩阵,角点周围的一个固定区域。
hog_descriptors:(1*d)向量,HOG 梯度直方图描述子。
当比例阈值 k 取 0.8 时,HOG 特征描述子的匹配结果如图所示,共匹配了 92 对点:
RANSAC 方法迭代 500 次,误差阈值取 0.02 时,一般会剔除大约 20 对点,结果如图所示:
可以发现用 HOG 描述角点所拟合出来的变换矩阵比直接用像素值描述角点要好一些。具体实现请见 Matlab 代码及代码注释。
前面的图像拼接直接将两张图上下叠加在了一起,导致最终的输出图片里融合区域存在明显的分界线。可以将重合区域的强度值除以 2,其他部分除以 1,但这其实表示的是左右两张图片的比重相同(equally weighted),这样输出的拼接结果分界还是比较明显。
实际上,重合区域左右两边的比重并不应该相同——靠近左边图片的部分,左边图片的比重应该更大;靠近右边图片的部分,右边图片的比重应该更大。我们可以利用线性融合的方法来提升拼接结果的质量。
linear_blend.m
img1:(HW3)经过仿射变换过后的图 1。
img2:(HW3)经过仿射变换过后的图 2。
temp_mask:img1 和 img2 的重合区域。
linear_blended_img:(HW3)重合区域比重相同融合结果。
equally_weighted_blended_img:(HW3)重合区域线性融合结果。
具体实现请见 Matlab 代码及代码注释。
这里采用了前面 HOG 描述子拟合变换后的 img1 和 img2,直接融合和线性融合结果如下:
以下是截止时间延长后的添加内容:
这个模块没什么新内容,只是把写完的函数放在了一块儿为全景拼接作准备。
1.角点检测;2.生成描述子;3.匹配角点;4.RANSAC;5.拟合矩阵;6.线性融合。
stitch.m
img1:(HW3)的图 1。
img2:(HW3)的图 2。
out:img1 和 img2 线性融合的拼接结果。
来不及自己写 SIFT 了,但是发现 Matlab 封装好了 SURF,这个模块是用 Matlab 自带函数实现的图像拼接。
Matlab 进行图像拼接的具体步骤和以上步骤相同,主要用到的函数有:
6.linear_blend();
my_surf.m
img1:(HW3)的图 1。
img2:(HW3)的图 2。
out:img1 和 img2 线性融合的拼接结果。
用 Matlab 自带的函数拼接结果如下:
可见效果比自己写的要更好一点儿。
从上面的结果可以看出自己写的函数实现效果没有 Matlab 的好,而且由于自己写的函数有各种各样的小问题,在截止时间之前完全自己实现全景拼接不太可能了,所以只能基于 Matlab 的代码加工一个全景拼接。
主要原理就是添加一个循环,每次拼接两张图片 img1 和 img2,经过一次循环后 img1 是每次的拼接结果,最后可以实现顺序输入图片的拼接。由于用的是 Matlab 已经封装好的函数,所以在变换矩阵拟合方面比较优秀。
但是最后研究了半天也不知道为啥最后结果右边有这么多黑边。拼接结果如下:
用了其他图片测试,拼接效果如下:
如果匹配效果不佳的话(如雪山),也许可以通过调整参数使匹配效果变好,由于时间关系没有继续研究参数了。
资源下载地址:https://download.csdn.net/download/sheziqiong/85824219
资源下载地址:https://download.csdn.net/download/sheziqiong/85824219
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。