1 Harris角点检测器
Harris角点检测算法是简单的角点检测算法,重要头脑是,如果像素附近表现存在多于一个方向的边,以为该点为爱好点,称为角点。
把图像域中点 x上的对称半正定矩阵 M r = M l ( x ) M_{r}=M_{l}(\mathbf{x}) Mr=Ml(x)界说为:
M 1 = ∇ I ∇ I T = [ I x I y ] [ I x I y ] = [ I x 2 I x I y I x I y I y 2 ] \boldsymbol{M}_1=\nabla\boldsymbol{I}\:\nabla\boldsymbol{I}^T=\begin{bmatrix}\boldsymbol{I}_x\\\boldsymbol{I}_y\end{bmatrix}\begin{bmatrix}\boldsymbol{I}_x&\boldsymbol{I}_y\end{bmatrix}=\begin{bmatrix}\boldsymbol{I}_x^2&\boldsymbol{I}_x\boldsymbol{I}_y\\\boldsymbol{I}_x\boldsymbol{I}_y&\boldsymbol{I}_y^2\end{bmatrix} M1=∇I∇IT=[IxIy][IxIy]=[Ix2IxIyIxIyIy2]
此中 ∇ I \nabla I ∇I 为包罗导数 I x I_x Ix 和 I y I_\mathrm{y} Iy的图像梯度 。由于该界说, M ι M_{\iota} Mι的秩为1,特性值为 λ 1 = ∣ ∇ I ∣ 2 \lambda_1=|\nabla I|^2 λ1=∣∇I∣2和 λ 2 = 0 \lambda_2=0 λ2=0。现在对于图像的每一个像素,我们可以盘算出该矩阵。
选择权重矩阵 W W W(通常为高斯滤波器 G σ G_\sigma Gσ),我们可以得到卷积:
M ‾ l = W ∗ M l \overline{M}_l=W*M_l Ml=W∗Ml
该卷积的目标是得到 M I M_I MI 在附近像素上的局部匀称。盘算出的矩阵 M ‾ I \overline{M}_I MI有称为 Harris矩阵。
取决于该地域 ∇ I 的值,Harris 矩阵 M ‾ i 的特性值有三种环境 : ∙ 如果 λ 1 和 λ 2 都是很大的正数,则该 x 点为角点 ; ∙ 如果 λ 1 很大, λ 2 ≈ 0 ,则该地域内存在一个边,该地域内的匀称 M i 的特性值不 会变革太大; ∙ 如果 λ 1 ≈ λ 2 ≈ 0 ,该地域内为空。 \begin{aligned}&\text{取决于该地域}\nabla\boldsymbol{I}\text{ 的值,Harris 矩阵}\overline{\boldsymbol{M}}_i\text{的特性值有三种环境}:\\&\bullet\text{ 如果 }\lambda_1\text{ 和 }\lambda_2\text{都是很大的正数,则该 }\mathbf{x}\text{ 点为角点};\\&\bullet\text{ 如果 }\lambda_1\text{ 很大,}\lambda_2\approx0\text{,则该地域内存在一个边,该地域内的匀称 }\boldsymbol{M}_i\text{的特性值不}\\&\text{会变革太大;}\\&\bullet\text{ 如果 }\lambda_1\approx\lambda_2\approx0\text{,该地域内为空。}\end{aligned} 取决于该地域∇I 的值,Harris 矩阵Mi的特性值有三种环境:∙ 如果 λ1 和 λ2都是很大的正数,则该 x 点为角点;∙ 如果 λ1 很大,λ2≈0,则该地域内存在一个边,该地域内的匀称 Mi的特性值不会变革太大;∙ 如果 λ1≈λ2≈0,该地域内为空。
- from matplotlib import pyplot as plt
- from PIL import Image
- from numpy import *
- from numpy import random
- from scipy.ndimage import filters
- def compute_harris_response(img, sigma=3):
- imgx = zeros(img.shape)
- filters.gaussian_filter(img, (sigma, sigma), (0, 1), imgx)
- imgy = zeros(img.shape)
- filters.gaussian_filter(img, (sigma, sigma), (1, 0), imgy)
- Wxx = filters.gaussian_filter(imgx * imgx, sigma)
- Wxy = filters.gaussian_filter(imgx * imgy, sigma)
- Wyy = filters.gaussian_filter(imgy * imgy, sigma)
- Wdet = Wxx * Wyy - Wxy * Wxy
- Wtran = Wxx + Wyy
- return Wdet / Wtran
- def get_harris_points(harrisimg, min_dist=10, threshold=0.1):
- corners = harrisimg.max() * threshold
- harrisimg_t = (harrisimg > corners) * 1
- coords = array(harrisimg_t.nonzero()).T
- candidate_values = [harrisimg[c[0], c[1]] for c in coords]
- index = argsort(candidate_values)
- allow_locations = zeros(harrisimg.shape)
- allow_locations[min_dist:-min_dist, min_dist:-min_dist] = 1
- filtered_coords = []
- for idx in index:
- if allow_locations[coords[idx][0], coords[idx][1]] == 1:
- filtered_coords.append(coords[idx])
- allow_locations[coords[idx][0] - min_dist:coords[idx][0] + min_dist,
- coords[idx][1] - min_dist:coords[idx][1] + min_dist] = 0
- return filtered_coords
- im = array(Image.open('jimei.jpg').convert('L'))
- harrisim = compute_harris_response(im)
- filtered_coords = get_harris_points(harrisim,6)
- plt.rcParams['font.sans-serif'] = ['SimHei']
- plt.subplot(121), plt.imshow(im, plt.cm.gray), plt.title('原始图像'), plt.axis('off')
- plt.subplot(122), plt.imshow(harrisim, plt.cm.gray), plt.title('角点图像'), plt.axis('off')
- plt.show()
复制代码
- 在图像间探求对应点
Harris角点检测器仅仅可以或许检测出图像中的爱好点,没有给出通过比力图像间的爱好点来探求匹副角点的方法。须要在每个点加入形貌子信息,给出一个比力形貌子的方法。
爱好点形貌子是分配给爱好点的一个向量,形貌该点附近的图像的表观信息。形貌子越好,探求到的对应点越好。
Harris 角点的形貌子通常是由附近图像像素块的灰度值,以及用于比力的归一化互
相干矩阵构成的。图像的像素块由以该像素点为中心的附近矩形部门图像构成。
通常,两个(类似巨细)像素块 I 1 ( x ) I_1(\mathbf{x}) I1(x) 和 I 2 ( x ) I_2(\mathbf{x}) I2(x)的相干矩阵界说为:
c ( I 1 , I 2 ) = ∑ x f ( I 1 ( x ) , I 2 ( x ) ) c(I_1,I_2)=\sum_xf(I_1(\mathbf{x}),I_2(\mathbf{x})) c(I1,I2)=x∑f(I1(x),I2(x))
此中,函数 f f f随着相干方法的变革而变革。上式取像素块中全部像素位置 x的和。对于相互关矩阵,函数 f ( I 1 , I 2 ) = I 1 I 2 f(\boldsymbol I_1,\boldsymbol{I}_2)=\boldsymbol{I}_1\boldsymbol{I}_2 f(I1,I2)=I1I2,因此, c ( I 1 , I 2 ) = I 1 ⋅ I 2 c(\boldsymbol I_1,\boldsymbol{I}_2)=\boldsymbol{I}_1\cdot\boldsymbol{I}_2 c(I1,I2)=I1⋅I2,此中·体现向量乘法(按照行大概列堆积的像素)。 c ( I 1 , I 2 ) c(I_1,I_2) c(I1,I2)的值越大,像素块 I 1 I_1 I1和 I 2 的相似度越高。 1 I_2\text{的相似度越高。}^1 I2的相似度越高。1
归一化的相互关矩阵是相互关矩阵的一种变形,可以界说为:
n c c ( I 1 , I 2 ) = 1 n − 1 ∑ x ( I 1 ( x ) − μ 1 ) σ 1 ⋅ ( I 2 ( x ) − μ 2 ) σ 2 ncc\left(\boldsymbol{I}_1,\boldsymbol{I}_2\right)=\frac{1}{n-1}\sum_{x}\frac{\left(\boldsymbol{I}_1(\mathbf{x})-\mu_1\right)}{\sigma_1}\cdot\frac{\left(\boldsymbol{I}_2(\mathbf{x})-\mu_2\right)}{\sigma_2} ncc(I1,I2)=n−11x∑σ1(I1(x)−μ1)⋅σ2(I2(x)−μ2)
此中, n n n为像素块中像素的数量, μ 1 \mu_1 μ1和 μ 2 \mu_2 μ2体现每个像素块中的匀称像素值强度, σ l \sigma_{\mathrm{l}} σl 和 σ 2 \sigma_{2} σ2分别体现每个像素块中的标准差。通过减去均值和除以标准差,该方法对图像亮度变革具有妥当性。
可以利用如下两个函数实现:
- def get_descriptors(image, filtered_coords, wid=5):
- desc = []
- for coord in filtered_coords:
- patch = image[coord[0] - wid:coord[0] + wid + 1, coord[1] - wid:coord[1] + wid + 1].flatten()
- desc.append(patch)
- return desc
- def match(desc1, desc2, threshold=0.5):
- n = len(desc1[0])
- d = -ones((len(desc1), len(desc2)))
- for i in range(len(desc1)):
- for j in range(len(desc2)):
- d1 = (desc1[i] - mean(desc1[i])) / std(desc1[i])
- d2 = (desc2[j] - mean(desc2[j])) / std(desc2[j])
- ncc_values = sum(d1 * d2) / (n - 1)
- if ncc_values > threshold:
- d[i, j] = ncc_values
- ndx = argsort(-d)
- matchscores = ndx[:, 0]
- return matchscores
复制代码 第一个函数的参数为奇数巨细长度的方形灰度图像块,该图像块的中心为处置惩罚的像素点。该函数将图像块像素值压平成一个向量,然后添加到形貌子列表中。第二个函数利用归一化的相互关矩阵,将每个形貌子匹配到另一个图像中的最优的候选点。
2 SIFT
SIFT特性包罗爱好点检测器和形貌子。SIFT形貌子具有非常强的妥当性,SIFT特性对于标准,旋转和亮度都具有稳固性,可用于三维视角和噪声的可靠匹配。
2.1 爱好点
SIFT 特性利用高斯差分函数来定位爱好点:
D ( x , σ ) = [ G κ σ ( x ) − G σ ( x ) ] ∗ I ( x ) = [ G κ σ − G σ ] ∗ I = I κ σ − I σ D(\mathbf{x},\sigma)=[G_{\kappa\sigma}(\mathbf{x})-G_{\sigma}(\mathbf{x})]*I(\mathbf{x})=[G_{\kappa\sigma}-G_{\sigma}]*I=I_{\kappa\sigma}-I_{\sigma} D(x,σ)=[Gκσ(x)−Gσ(x)]∗I(x)=[Gκσ−Gσ]∗I=Iκσ−Iσ
此中, G σ G_\sigma Gσ是上一章中先容的二维高斯核, I σ I_\sigma Iσ是利用 G σ G_\sigma Gσ含糊的灰度图像, κ \kappa κ是决定相差标准的常数。爱好点是在图像位置和标准变革下 D ( x , σ ) D(\mathbf{x},\sigma) D(x,σ)的最大值和最小值点。
2.2 形貌子
为了实现旋转稳固性,基于每个点附近图像梯度的方向和巨细,SIFT形貌子引入了参考方向。SIFT形貌子利用主方向形貌参考方向。主方向利用方向直方图来度量。
2.3 检测爱好点
可以利用开源工具包VLFeat提供的二进制文件来盘算图像的SIFT特性。
- from PIL import Image
- from pylab import *
- from PCV.localdescriptors import sift
- from PCV.localdescriptors import harris
- from matplotlib.font_manager import FontProperties
- font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
- imname = 'D:\\Python\\chapter2\\jimei2.jpg'
- im = array(Image.open(imname).convert('L'))
- sift.process_image(imname, 'empire.sift')
- l1, d1 = sift.read_features_from_file('empire.sift')
- figure()
- gray()
- subplot(131)
- sift.plot_features(im, l1, circle=False)
- title(u'(a)SIFT特征', fontproperties=font)
- subplot(132)
- sift.plot_features(im, l1, circle=True)
- title(u'(b)用圆圈表示SIFT特征尺度', fontproperties=font)
- # 检测harris角点
- harrisim = harris.compute_harris_response(im)
- subplot(133)
- filtered_coords = harris.get_harris_points(harrisim, 6, 0.1)
- imshow(im)
- plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')
- axis('off')
- title(u'(c)Harris角点', fontproperties=font)
- show()
复制代码 2.4 匹配形貌子
对于将一幅图像中的特性匹配到另一幅图像的特性,一种妥当的准则是利用这两个特性间隔和两个最匹配特性间隔的比率。
- from PIL import Image
- from pylab import *
- import sys
- from PCV.localdescriptors import sift
- if len(sys.argv) >= 3:
- im1f, im2f = sys.argv[1], sys.argv[2]
- else:
- im1f = 'D:\Data\xiaoqu.jpg'
- im2f = 'D:\Data\JiMei.jpg'
- im1 = array(Image.open(im1f))
- im2 = array(Image.open(im2f))
- sift.process_image(im1f, 'out_sift_1.txt')
- l1, d1 = sift.read_features_from_file('out_sift_1.txt')
- figure()
- gray()
- subplot(121)
- sift.plot_features(im1, l1, circle=False)
- sift.process_image(im2f, 'out_sift_2.txt')
- l2, d2 = sift.read_features_from_file('out_sift_2.txt')
- subplot(122)
- sift.plot_features(im2, l2, circle=False)
- matches = sift.match_twosided(d1, d2)
- print '{} matches'.format(len(matches.nonzero()[0]))
- figure()
- gray()
- sift.plot_matches(im1, im2, l1, l2, matches, show_below=True)
- show()
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |