Python实现Harris角点检测算法详解

不晚
不晚
发布时间:2026-10-14 | 4人浏览过
原创

本文详细解析Harris角点检测算法的实现流程,涵盖灰度转换、Sobel滤波、高斯平滑及角点响应值计算等关键步骤。通过Python结合OpenCV与NumPy提供完整代码示例,并展示原图与检测结果对比,帮助开发者快速掌握角点检测的核心逻辑与应用方法。

算法处理流程如下:

  1. 首先,将输入的彩色图像转换为灰度图像,以简化后续计算。
  2. 接着,利用Sobel滤波器计算图像的梯度,进而构建海森矩阵(Hessian matrix)。

  • 随后,分别使用高斯滤波器对海森矩阵中的分量Ix²、Iy²以及IxIy进行平滑处理,以增强算法的鲁棒性。
  • 计算每个像素点的角点响应值R,公式为R = det(H) - k(trace(H))²。其中,det(H)代表矩阵H的行列式,trace(H)代表矩阵H的迹。系数k的取值范围通常在[0.04, 0.16]之间,具体数值需根据应用场景调整。
  • 最后,筛选出满足条件R >= max(R) * th的像素点作为角点。阈值th通常设定为0.1,用于控制角点检测的敏感度。

以下是基于Python的Harris角点检测算法的具体代码实现。


import cv2 as cv 
import numpy as np
import matplotlib.pyplot as plt


# Harris corner detection
def Harris_corner(img):

	## Grayscale
	def BGR2GRAY(img):
		gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
		gray = gray.astype(np.uint8)
		return gray

	## Sobel
	def Sobel_filtering(gray):
		# get shape
		H, W = gray.shape

		# sobel kernel
		sobely = np.array(((1, 2, 1),
						(0, 0, 0),
						(-1, -2, -1)), dtype=np.float32)

		sobelx = np.array(((1, 0, -1),
						(2, 0, -2),
						(1, 0, -1)), dtype=np.float32)

		# padding
		tmp = np.pad(gray, (1, 1), 'edge')

		# prepare
		Ix = np.zeros_like(gray, dtype=np.float32)
		Iy = np.zeros_like(gray, dtype=np.float32)

		# get differential
		for y in range(H):
			for x in range(W):
				Ix[y, x] = np.mean(tmp[y : y + 3, x : x + 3] * sobelx)
				Iy[y, x] = np.mean(tmp[y : y + 3, x : x + 3] * sobely)
			
		Ix2 = Ix ** 2
		Iy2 = Iy ** 2
		Ixy = Ix * Iy

		return Ix2, Iy2, Ixy


	# gaussian filtering
	def gaussian_filtering(I, K_size=3, sigma=3):
		# get shape
		H, W = I.shape

		## gaussian
		I_t = np.pad(I, (K_size // 2, K_size // 2), 'edge')

		# gaussian kernel
		K = np.zeros((K_size, K_size), dtype=np.float)
		for x in range(K_size):
			for y in range(K_size):
				_x = x - K_size // 2
				_y = y - K_size // 2
				K[y, x] = np.exp( -(_x ** 2 + _y ** 2) / (2 * (sigma ** 2)))
		K /= (sigma * np.sqrt(2 * np.pi))
		K /= K.sum()

		# filtering
		for y in range(H):
			for x in range(W):
				I[y,x] = np.sum(I_t[y : y + K_size, x : x + K_size] * K)
				
		return I

	# corner detect
	def corner_detect(gray, Ix2, Iy2, Ixy, k=0.04, th=0.1):
		# prepare output image
		out = np.array((gray, gray, gray))
		out = np.transpose(out, (1,2,0))

		# get R
		R = (Ix2 * Iy2 - Ixy ** 2) - k * ((Ix2 + Iy2) ** 2)

		# detect corner
		out[R >= np.max(R) * th] = [255, 0, 0]

		out = out.astype(np.uint8)

		return out

	
	# 1. grayscale
	gray = BGR2GRAY(img)

	# 2. get difference image
	Ix2, Iy2, Ixy = Sobel_filtering(gray)

	# 3. gaussian filtering
	Ix2 = gaussian_filtering(Ix2, K_size=3, sigma=3)
	Iy2 = gaussian_filtering(Iy2, K_size=3, sigma=3)
	Ixy = gaussian_filtering(Ixy, K_size=3, sigma=3)

	# 4. corner detect
	out = corner_detect(gray, Ix2, Iy2, Ixy)

	return out


# Read image
img = cv.imread("../qiqiao.jpg").astype(np.float32)

# Harris corner detection
out = Harris_corner(img)

cv.imwrite("out.jpg", out)
cv.imshow("result", out)
cv.waitKey(0)
cv.destroyAllWindows()

实验验证部分展示了算法的实际运行效果。

测试使用的原始图像如下。

经过Harris角点检测算法处理后,检测到的角点结果如图所示。

以上为Python实现Harris角点检测算法的完整内容,如需了解更多相关技术细节,建议查阅本站其他相关文章。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表