本文的目的是使用python实现moravec点特征提取算子下面为本人的思路以及实现代码(本人是河南理工大学遥感2002班的一名学生,本代码仅供参考,如有错误欢迎指正,成老师座下大弟子!)
1、首先读取图像的灰度图像
2、定义兴趣值窗口大小
3、定义与目标大小相同的单通道兴趣矩阵计算每个点的兴趣值并储存每个像素的兴趣值
4、设置一个阈值大小,将兴趣值矩阵中的小于阈值的兴趣值全部变为
5、定义一个抑制窗口,并将其放入兴趣值矩阵中进行滑动,如果窗口中心的兴趣值为窗口矩阵的最大值,这个中心点就是特征点,将其坐标储存起来6、将特征点坐标在图像上表示出来
代码如下:
import numpy as np
import cv2
import math
#读取灰度图像
img=cv2.imread(r"C:\Users\lihuiliang\Desktop\photo\meinv.bmp",0)
image=cv2.imread(r"C:\Users\lihuiliang\Desktop\photo\meinv.bmp",1)
#读取为先列后行就是有(y,x)
h,w=img.shape
#创建一个大小和原图片相同的二维数组
img_huidu=np.zeros((w,h))
#将原图像的像素灰度值存入灰度矩阵
#将行列转换回来为正常的行列
for i in range(w):
for j in range(h):
img_huidu[i][j]=img[j][i]
#定义一个指定大小的兴趣窗口winsize
#其一半大小为k
#创建一个矩阵
winsize=5#兴趣窗口
k=int(winsize/2)
inter=np.zeros((w,h))#兴趣值矩阵
#以左上角为原点从(k,k)开始滑动进行四个方向的灰度计算并将其放入兴趣值矩阵
X_xian_1=k
X_xian_2=w-X_xian_1
Y_xian1=k
Y_xian2=h-Y_xian1
#x
for i in range(k,X_xian_2):
#y
for j in range(k,Y_xian2):
v1=(img_huidu[i+1][j]-img_huidu[i][j])**2+(img_huidu[i-1][j]-img_huidu[i][j])**2
v2=(img_huidu[i][j-1]-img_huidu[i][j])**2+(img_huidu[i][j+1]-img_huidu[i][j])**2
v3=(img_huidu[i+1][j-1]-img_huidu[i][j])**2+(img_huidu[i-1][j+1]-img_huidu[i][j])**2
v4=(img_huidu[i-1][j-1]-img_huidu[i][j])**2+(img_huidu[i+1][j+1]-img_huidu[i][j])**2
v_min=min(v1,v2,v3,v4)
inter[i][j]=v_min
#处理兴趣值矩阵将小于阈值的兴趣值改为0
#设置阈值
y=200
for i in range(w):
for j in range(h):
if inter[i][j]<y:
inter[i][j]=0
#设置一个抑制局部非最大窗口窗口大小为k
k=7
zk=int(k/2)
#定义一个x,y数组
x=[]
y=[]
#从大矩阵里面提取出窗口子矩阵
for i in range(w):
for j in range(h):
A=np.array(inter[k+i-5:k+i+4,k+i-5:k+i+4])
if A.size!=0:
#求矩阵中最大值
a=A.max()
if inter[i][j]== a and inter[i][j] !=0:
x.append(i)
y.append(j)
print(x)
print(y)
#在图像上将这些候选点标记出来,这里用的是十字标记
#首先获取元素个数
men=len(x)
print(men)
for i in range(men):
image=cv2.drawMarker(image,(x[i],y[i]),(0,255,0),markerType=0)
cv2.imshow('img',image)
cv2.waitKey(0)