最近在上数字图像处理课程,需要使用Python手动编写Harris角点检测算法,但是网上几乎没有找到手动编写的,只能手敲。
同时作为自己的第一篇博客,在这里记录一下。
一、Harris角点检测
原理(略)
可以参考博主 拾牙慧者 的博客
角点检测(Harris角点检测法)_拾牙慧者的博客-CSDN博客_harris角点检测
二、Python中的Harris角点检测函数
Opencv库自带函数:cornerHarris()函数
void cornerHarris( InputArray src, OutputArray dst, int block Size, int ksize, double k, int borderType = BORDER_DEFAULT)
参数如下
1.InputArray类型的src,输入图像,即原图像,填Mat类型即可,且需要为单通道8位或者浮点型图像;
2.OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放Harris角点检测的输出结果,和原图片有一样的尺寸和类型;
3.int类型的blockSize,表示邻域的大小,更多详细信息在cornerEigenValsAndVecs()中讲到;
4.int类型的ksize,表示Sobel()算子的孔径的大小;
5.double类型的k,Harris参数;
6.int类型的borderType,图像像素的边界模式。注意它有默认值BORDER_DEFAULT;
使用方法
import cv2
import numpy as np
img = cv2.imread('exp3/NEU_library.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = gray.astype(np.float32)
dst = cv2.cornerHarris(gray,5,3,0.04)
img[dst>0.01*dst.max()] = [0,0,255]
cv2.imshow('',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果如下(东北大学宁恩承图书馆)
三、手动写Python代码实现Harris焦点检测算法
import cv2
import numpy as np
def My_corner_Harris(image, blockSize, ksize, k):
#将图片转化为灰度图像,并转化类型为float32
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
src = gray_img.astype(np.float32)
#获取图像长和高
SrcHeight = src.shape[0]
SrcWidth = src.shape[1]
#利用Sobel函数计算图像梯度
#src为原图像,-1表示输出图像大小与原图像相同
#ksize为sobel算子,定义为角点检测敏感度,必须为3-31之间的奇数
#(1,0)表示对x求偏导,(0,1)表示对y求偏导
Ix=cv2.Sobel(src,-1,1,0,ksize)
Iy=cv2.Sobel(src,-1,0,1,ksize)
#计算Ix2, Ixy, Iy2
Ix2=np.multiply(Ix,Ix)
Ixy=np.multiply(Ix,Iy)
Iy2=np.multiply(Iy,Iy)
#使用高斯平滑滤波进行加权计算
Ix2=cv2.GaussianBlur(Ix2,(blockSize,blockSize),1.3)
Ixy=cv2.GaussianBlur(Ixy,(blockSize,blockSize),1.3)
Iy2=cv2.GaussianBlur(Iy2,(blockSize,blockSize),1.3)
#计算最后的R值
R=np.zeros((SrcHeight,SrcWidth))#定义空的R矩阵
for i in range(SrcHeight):
for j in range(SrcWidth):
M=np.array([[Ix2[i,j],Ixy[i,j]],[Ixy[i,j],Iy2[i,j]]])
R[i,j]= np.linalg.det(M) - k * ((M.trace())**2)
return R
# detector parameters
block_size = 5
sobel_size = 3
k = 0.04
image = cv2.imread('exp3/NEU_library.jpg')
R = My_corner_Harris(image, block_size, sobel_size, k)
image[R>0.01*R.max()] = [0,0,255]
cv2.imshow('detection result', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
测试一下结果
和官方的cornerHarris()函数对比一下
cornerHarris() My_corner_Harris
四、总结
1.简单手动实现Harris角点检测算法,未进行改进
2.可以考虑非极大值进行抑制,参考Harris角点算法 - bldong - 博客园 (cnblogs.com)
3.后续会考虑实现Shi-Tomasi、亚像素检测等方法,做出来的话会更新。
此致
感谢阅读
WSZYM
2022.12.01
版权归原作者 WSZYM♡181101 所有, 如有侵权,请联系我们删除。