提取点特征的算子称为兴趣算子或有利算子(interest operator),即运用某种算法从影像中提取我们所感兴趣的,即有利于某种目的的点。现在已提出了一系列算法各异,且具有不同特色的兴趣算子,比较知名的有Moravec点特征提取算子等,该算子是由Moravec于1977年提出,它是一种利用灰度方差提取点特征的算子。
Moravec点特征提取算子的基本原理步骤如下。
如图1所示,中心像素为(c,r),则该窗口四个方向相邻像素灰度差的平方和为:
V 1 = ∑ i = − k k − 1 ( g c + i , r −    g   c + i + 1 , r ) 2    V 2 = ∑ i = − k k − 1 ( g c + i , r + i −    g   c + i + 1 , r + i + 1 ) 2 V 3 = ∑ i = − k k − 1 ( g c , r + i −    g   c , r + i + 1 ) 2    V 4 = ∑ i = − k k − 1 ( g c + i , r − i −    g   c + i + 1 , r − i − 1 ) 2 } \left.\begin{array}{r}\begin{array}{c}V1=\sum_{i=-k}^{k-1}\left(g_{c+i,r}-\;g\,_{c+i+1,r}\right)^2\;\\V2=\sum_{i=-k}^{k-1}\left(g_{c+i,r+i}-\;g\,_{c+i+1,r+i+1}\right)^2\\V3=\sum_{i=-k}^{k-1}\left(g_{c,r+i}-\;g\,_{c,r+i+1}\right)^2\;\end{array}\\\begin{array}{c}V4=\sum_{i=-k}^{k-1}\left(g_{c+i,r-i}-\;g\,_{c+i+1,r-i-1}\right)^2\end{array}\end{array}\right\} V1=∑i=−kk−1(gc+i,r−gc+i+1,r)2V2=∑i=−kk−1(gc+i,r+i−gc+i+1,r+i+1)2V3=∑i=−kk−1(gc,r+i−gc,r+i+1)2V4=∑i=−kk−1(gc+i,r−i−gc+i+1,r−i−1)2⎭⎪⎪⎪⎬⎪⎪⎪⎫
其中, k = i n t ( w 2 ) k=int\left(\frac w2\right) k=int(2w)
取其中的最小者作为该像素点(c,r)的兴趣值,即:
I V = m i n ( V 1 , V 2 , V 3 , V 4 ) IV=min\left(V1,V2,V3,V4\right) IV=min(V1,V2,V3,V4)
给定一阈值,将兴趣值大于该阈值的点作为候选点。
选取候选点中的极值点作为特征点。即在一定大小的窗口内,将候选点中兴趣值不是最大的去掉,仅留下一个兴趣值最大者,这一操作也称为非极大值抑制。
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img=np.array(Image.open('.\pic.bmp'))
rows,cols=img.shape # 获取图像长宽
# 显示原图像
plt.figure("原图")
plt.imshow(img,cmap='gray')
plt.axis('off')
# 计算各像元的兴趣值
m_hx= [[0 for i in range(cols)] for i in range(rows)]
bMatrix=[[0 for i in range(cols)] for i in range(rows)]
z=False
for i in range(5, rows-5, 1):
for j in range(5, cols-5, 1):
a=((int(img[i-2,j-2])-int(img[i-1,j-1]))**2+(int(img[i,j])-int(img[i-1,j-1]))**2+(int(img[i,j])-int(img[i+1,j+1]))**2+(int(img[i+2,j+2])-int(img[i+1,j+1]))**2)
b=((int(img[i-2,j])-int(img[i-1,j]))**2+(int(img[i-1,j])-int(img[i,j]))**2+(int(img[i,j])-int(img[i+1,j]))**2+(int(img[i+2,j])-int(img[i+1,j]))**2)
c=((int(img[i-2,j+2])-int(img[i-1,j+1]))**2+(int(img[i,j])-int(img[i-1,j+1]))**2+(int(img[i,j])-int(img[i+1,j-1]))**2+(int(img[i+2,j-2])-int(img[i+1,j-1]))**2)
d=((int(img[i,j-2])-int(img[i,j-1]))**2+(int(img[i,j])-int(img[i,j-1]))**2+(int(img[i,j])-int(img[i,j+1]))**2+(int(img[i,j+2])-int(img[i,j+1]))**2)
m_xq=min(a, b, c, d) # 取其中的最小者作为该像素点的兴趣值
# 设置阈值,选取候选点
if m_xq>2000:
m_hx[i][j]=m_xq
# 非极大值抑制
for i in range(5, rows-5,1 ):
for j in range(5, cols-5,1 ):
max=0
for m in range(i-2, i+2, 1):
for n in range(j-2, j+2, 1):
if m_hx[m][n]>max:
max=m_hx[m][n]
m1=m
n1=n
z=True
if z==True:
bMatrix[m1][n1]= 1
# 将提取出的特征点用白色十字在原图中表示出来
for i in range(rows-2):
for j in range(cols-2):
if bMatrix[i][j]==1:
img[i+1][j]=255
img[i][j]=255
img[i-1][j]=255
img[i][j+1]=255
img[i][j-1]=255
img[i][j+2]=255
img[i][j-2]=255
img[i+2][j]=255
img[i-2][j]=255
plt.figure("特征")
plt.imshow(img,cmap='gray')
plt.axis('off')
plt.show()
[1] 张祖勋, 张剑清. 数字摄影测量学[M]. 武汉大学出版社, 1997.