首页 > 解决方案 > 角点检测中的非最大抑制

问题描述

我正在用 Python 编写 Harris 角点检测算法,并且正在执行非最大抑制以检测角点。

我发现角落响应函数R在我打印出来时似乎是准确的,但是我不知道从哪里开始。我大致理解了非最大抑制的概念,即取窗口内强度最高的像素,将其设置为角点,其余设置为 0。虽然我不知道在实现方面如何去做。

在计算之后,我是否会使用它创建的地图将原始图像中的这些像素设置为特定颜色(以指示哪些是角)?

到目前为止,我的代码如下:

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

# Load image
img = cv2.imread('mountains.jpg')

# Make a copy of the image
img_copy = np.copy(img)

# Convert image from BGR to RGB
img_copy = cv2.cvtColor(img_copy, cv2.COLOR_BGR2RGB)

# Convert to grayscale for filtering
gray = cv2.cvtColor(img_copy, cv2.COLOR_RGB2GRAY)

# Copy grayscale and convert to float32 type
gray_1 = np.copy(gray)
gray_1 = np.float32(gray_1)
img_1 = np.copy(img)

# Compute derivatives in both x and y directions
sobelx = cv2.Sobel(gray_1, cv2.CV_64F, 1, 0, ksize=5)
sobely = cv2.Sobel(gray_1, cv2.CV_64F, 0, 1, ksize=5)

# Determine M = [A C ; C B] performing element-wise multiplication
A = np.square(sobelx)
B = np.square(sobely)
C = np.multiply(sobelx, sobely)

# Apply gaussian filter to matrix components
gauss = np.array([[1, 2, 1],
                  [2, 4, 2], 
                  [1, 2, 1]])/16

A_fil = cv2.filter2D(A, cv2.CV_64F, gauss)
B_fil = cv2.filter2D(B, cv2.CV_64F, gauss)
C_fil = cv2.filter2D(C, cv2.CV_64F, gauss)

# Calculate determinant
det = A_fil * B_fil - (C_fil ** 2)

# Calculate trace (alpha = 0.04 to 0.06)
alpha = 0.04
trace = alpha * (A_fil + B_fil) ** 2

# Using determinant and trace, calculate corner response function
R = det - trace

# Display corner response function
f, ax1 = plt.subplots(1, 1, figsize=(20,10))

ax1.set_title('Corner response fuction')
ax1.imshow(R, cmap="gray")

(注意:堆栈溢出图像无法正常工作)

输出:

输出

使用 OpenCV 的 Harris 角点检测:

开放式CV

标签: pythonopencv

解决方案


已经有一段时间了,所以您可能已经有了答案,但由于尚未有人回复,我将把它留给后代。

下面是一个简单的非最大抑制算法:

  • 将您的图像划分为图块(例如 64 x 48 像素)
  • 选择最小分离空间(例如,特征之间 >= 10 像素)
  • 选择每个图块的最大特征数(例如 5 个)

按 R(从高到低)对每个窗口图块中的特征进行排序,然后只接受(最多)5 个与其他特征至少相距 10 像素的最大特征。您将无法保证窗砖之间的最小距离为 10 像素,但这是一个合理的开始。


推荐阅读