文章目录
前言
本章旨在寻找图像间的对应点和对应区域。图像匹配是指通过一定的匹配算法在两幅或多幅图像之间识别同名点,如二维图像匹配中通过比较目标区和搜索区中相同大小的窗口的相关系数,取搜索区中相关系数最大所对应的窗口中心点作为同名点。其实质是在基元相似性的条件下,运用匹配准则的最佳搜索问题。
特征匹配基本流程:
1.根据准则,提取图像中的特征点
2.提取特征点周围的图像块,构造特征描述符
3.通过特征描述符对比,实习特征匹配
同时,特征点必须具有不变性,比如:
1.几何不变性:位移、旋转、尺度……
2.光度不变性:关照、曝光……
接下来,我们将学习两种常用的图像匹配算法。
Harris 角点检测算法:用于提取图像的特征点;
SIFT:用于解决图像缩放、旋转、曝光、噪声等因素对特征匹配的影响。
1. Harris角点检测
1.1 基本原理
Harris角点检测算法(也称Harris & Stephens角点检测器)是一个极为简单的角点 检测算法。该算法的主要思想是,如果像素周围显示存在多于一个方向的边,我们 认为该点为兴趣点。该点就称为角点。
我们把图像域中点 x 上的对称半正定矩阵 MI=MI(x)定义为:
其中 ∇ I ∇I ∇I 为包含导数 I x Ix Ix 和 I y Iy Iy 的图像梯度。由于该定义, M I MI MI 的秩为 1,特征值为 λ 1 = ∣ ∇ I ∣ 2 和 λ 2 = 0 λ1=|∇I|2和 λ2=0 λ1=∣∇I∣2和λ2=0。现在对于图像的每一个像素,我们可以计算出该矩阵。
选择权重矩阵 W(通常为高斯滤波器 Gσ),我们可以得到卷积:
该卷积的目的是得到 M I MI MI在周围像素上的局部平均。计算出的矩阵 M I MI MI有称为 Harris矩阵。 W W W的宽度决定了在像素 x x x周围的感兴趣区域。像这样在区域附近对矩阵 M I MI MI取平均的原因是,特征值会依赖于局部图像特性而变化。如果图像的梯度在该区域 变化,那么 M I MI MI的第二个特征值将不再为 0。如果图像的梯度没有变化, M I MI MI的特征 值也不会变化。
取决于该区域 I的值,Harris矩阵MI的特征值有三种情况:
如果λ1和λ2都是很大的正数,则该x点为角点;
如果 λ1 很大,λ2 ≈ 0,则该区域内存在一个边,该区域内的平均 MI 的特征值不会变化太大;
如果λ1≈λ2≈0,该区域内为空。
在不需要实际计算特征值的情况下,为了把重要的情况和其他情况分开,Harris和Stephens 在文献 [12] 中引入了指示函数:
为了消除参数κ的影响,我们通常使用商数来计算:
1.2 基于Python的代码实现
代码如下:
# 局部图像描述子
# Harris角点检测
from pylab import *
from PIL import Image
import numpy as np
from scipy.ndimage import filters
def compute_harris_response(im, sigma=3):
"""在一幅灰度图像中,对每个像素计算Harris角点检测器响应函数"""
# 计算导数
imx = np.zeros(im.shape)
filters.gaussian_filter(im, (sigma, sigma), (0, 1), imx)
imy = np.zeros(im.shape)
filters.gaussian_filter(im, (sigma, sigma), (1, 0), imy)
# 计算Harris矩阵的分量
Wxx = filters.gaussian_filter(imx * imx, sigma)
Wxy = filters.gaussian_filter(imx * imy, sigma)
Wyy = filters.gaussian_filter(imy * imy, sigma)
# 计算特征值和迹
Wdet = Wxx * Wyy - Wxy ** 2
Wtr = Wxx + Wyy
return Wdet / Wtr
def get_harris_points(harrisim, min_dist=10, threshold=0.1):
"""从一幅Harris响应图像中返回角点。min_dist为分割角点和图像边界的最小像素数目"""
# 寻找高于阈值的候选角点
corner_threshold = harrisim.max() * threshold
harrisim_t = (harrisim > corner_threshold) * 1
# 得到候选点的坐标
coords = np.array(harrisim_t.nonzero()).T
# 以及它们的Harris响应值
candidate_values = [harrisim[c[0], c[1]] for c in coords]
# 对候选点按照Harris响应值进行排序
index = argsort(candidate_values)
# 将可行点的位置保存到数组中
allowed_locations = np.zeros(harrisim.shape)
allowed_locations[min_dist:-min_dist, min_dist:-min_dist] = 1
# 按照min_distance原则,选择最佳Harris点
filtered_coords = []
for i in index:
if allowed_locations[coords[i, 0], coords[i, 1]] == 1:
filtered_coords.append(coords