基于Python手动实现Harris角点检测

最近在上数字图像处理课程,需要使用Python手动编写Harris角点检测算法,但是网上几乎没有找到手动编写的,只能手敲。

基于Python手动实现Harris角点检测_第1张图片

同时作为自己的第一篇博客,在这里记录一下。

一、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

你可能感兴趣的:(opencv,计算机视觉,人工智能)