1. 简介

角点:个人理解就是图像中,带角的那些点(也不一定是尖锐的,导数为0的极值点也行)。它通常具有旋转不变性和光照不变性和视角不变性等优点,是图像的重要特征之一。他具有如下特点:

opencv 基于角点的直线检测 opencv角点检测harris_角点

2. 算法整体思想:

算法的核心是利用局部窗口在图像上进行移动,判断灰度是否发生较大的变化。如果窗口内的灰度值(在梯度图上)都有较大的变化,那么这个窗口所在区域就存在角点。

这样就可以将 Harris 角点检测算法分为以下三步:

  • 当窗口(局部区域)同时向 x (水平)和 y(垂直) 两个方向移动时,计算窗口内部的像素值变化量 $E(x,y)$ ;
  • 对于每个窗口,都计算其对应的一个角点响应函数 $R$;
  • 然后对该函数进行阈值处理,如果 $R > threshold$,表示该窗口对应一个角点特征。

3.opencv实现(python)

在opencv中有提供实现 Harris 角点检测的函数 cv2.cornerHarris,我们直接调用的就可以,非常方便。

函数原型:cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])

对于每一个像素 (x,y),在 (blockSize x blockSize) 邻域内,计算梯度图的协方差矩阵 $M(x,y)$,然后通过上面第二步中的角点响应函数得到结果图。图像中的角点可以为该结果图的局部最大值。

即可以得到输出图中的局部最大值,这些值就对应图像中的角点。

参数解释:

  • src - 输入灰度图像,float32类型
  • blockSize - 用于角点检测的邻域大小,就是上面提到的窗口的尺寸
  • ksize - 用于计算梯度图的Sobel算子的尺寸
  • k - 用于计算角点响应函数的参数k,取值范围常在0.04~0.06之间

具体python实现代码:

"""
harris 角点检测
从图像中检测属于 角点 的点信息
"""

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


# 检测器参数
block_size = 3  # 窗口尺寸大小
sobel_size = 3  # sobel算子尺寸大小
k = 0.06  # 用于计算相应角点R函数的k参数

image = cv.imread('data/fangzi_pic.png')  # 你需要检测的图片

print(image.shape)
height = image.shape[0]
width = image.shape[1]
channels = image.shape[2]
print("width: %s  height: %s  channels: %s" % (width, height, channels))

gray_img = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

# modify the data type setting to 32-bit floating point
gray_img = np.float32(gray_img)

# 检测角点
corners_img = cv.cornerHarris(gray_img, block_size, sobel_size, k)

# 膨胀处理,利于更方便的观察角点形态
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.dilate(corners_img, kernel)


# 晒出那些不合适的角点,pix大于一定阈值的认为是需要留下的角点
for r in range(height):
    for c in range(width):
        pix = dst[r, c]
        # if pix > 0.05 * dst.max():
        if pix > 0.1 * dst.max():
            cv.circle(image, (c, r), 5, (0, 0, 255), 0)  # 在图上角点处画小圆

image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
plt.imshow(image)
plt.show()

检测结果:

(1)原图 -------------------->

opencv 基于角点的直线检测 opencv角点检测harris_邻域_02

(2) 检测结果图 --------------------->

opencv 基于角点的直线检测 opencv角点检测harris_opencv_03