【图像处理】利用python实现Moravec点特征提取

提取点特征的算子称为兴趣算子或有利算子(interest operator),即运用某种算法从影像中提取我们所感兴趣的,即有利于某种目的的点。现在已提出了一系列算法各异,且具有不同特色的兴趣算子,比较知名的有Moravec点特征提取算子等,该算子是由Moravec于1977年提出,它是一种利用灰度方差提取点特征的算子。


算法原理

Moravec点特征提取算子的基本原理步骤如下。

  • 计算各像元的兴趣值IV(interest value)。即计算各像元四个方向相邻像素灰度差的平方和,取其中的最小值作为该像素的兴趣值。
图1 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=kk1(gc+i,rgc+i+1,r)2V2=i=kk1(gc+i,r+igc+i+1,r+i+1)2V3=i=kk1(gc,r+igc,r+i+1)2V4=i=kk1(gc+i,rigc+i+1,ri1)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()

结果图

图2 原图

图3 Moravec点特征提取图

参考文献

[1] 张祖勋, 张剑清. 数字摄影测量学[M]. 武汉大学出版社, 1997.

你可能感兴趣的:(【图像处理】利用python实现Moravec点特征提取)