OpenCV—python 角点特征检测之一(cornerHarris、Shi-Tomasi、FAST) - Go语言中文社区

OpenCV—python 角点特征检测之一(cornerHarris、Shi-Tomasi、FAST)


一、cornerHarris() 函数

cornerHarris() 角点检测具有旋转不变特性。关于角点检测用一幅图来讲解:

  • 红框进行移动:无论是往哪个方向进行偏移,都会对框框内的像素值造成很大的变动。那么红框 框住的区域的边角点,就是检测到的角点。
  • 黑框进行移动:水平方向上移动像素值的变化不大,垂直方向上移动那么就会变化很大;或者相反,则这种一般称为边缘区域。
  • 蓝框进行移动:无论是水平还是垂直的方向移动,框内像素值的变化不大。这种是内部区域。
    在这里插入图片描述
    1988 年的文章《A CombinedCorner and Edge Detector》中就已经提出了焦点检测的方法,被称为Harris 角点检测。他把这个简单的想法转换成了数学形式。将窗口向各个方向移动 (u,v)(u,v) 然后计算所有差异的总和。表达式如下:
    E(u,v)=x,yw(x,y)window function[I(x+u,y+v)shifted intensityI(x,y)]2intensityE(u,v) = sum_{x,y} underbrace{w(x,y)}_{window function} underbrace{[I(x+u,y+v)}_{shifted intensity}-underbrace{I(x,y)]^2}_{intensity}

窗口函数(Sobel求导中使用的窗口) :可以是正常的矩形窗口,也可以是对每一个像素给予不同权重的高斯窗口
角点检测中要使 E(μ,ν)E(μ,ν) 的值最大。这就是说必须使方程右侧的第二项的取值最大。对上面的等式进行泰勒级数展开然后再通过几步数学换算(可以参考其他标准教材),我们得到下面的等式:
E(u,v)=[uv]M[uv]E(u,v) = begin{bmatrix} u & v end{bmatrix}approx Mbegin{bmatrix} u\ vend{bmatrix}

其中:
E(u,v)=x,yw(x,y)[Ix2IxIyIxIyIy2]E(u,v) = sum_{x,y}w(x,y)begin{bmatrix}I_x^2 & I_xI_y\I_xI_y & I_y^2end{bmatrix}

这里 Ixrm I_x详情请点击。

他们根据一个用来判定窗口内是否包含角点的等式进行打分。

R=det(M)k(trace(M))2R = det(M) - k(trace(M))^2

其中:
det(M)=λ1λ2det(M) = lambda_1 lambda_2

trace(M)=λ1+λ2trace(M) = lambda_1+lambda_2

λ1λ1λ2λ2 是矩阵 M 的特征值:我们可以判断一个区域是否是角点,边界或者是平面。

  • λ1λ1λ2λ2 都小时,|R| 也小,这个区域就是一个平坦区域
  • λ1λ2λ1gg λ2
  • λ1λ1 和 λ2 都很大,并且λ1λ1λ2λ2 中的时,R 也很大,(λ1λ1λ2λ2中的最小值都大于阈值)说明这个区域是角点
    可以用下图来表示我们的结论:
    对比图
    http://www.bubuko.com/infodetail-2498014.html
    cv2.cornerHarris()函数的返回值其实就是R值构成的灰度图像 灰度图像坐标会与原图像对应  R值就是角点分数 当R值很大的时候 就可以认为这个点是一个角点
cv2.cornerHarris(src=gray, blockSize, ksize, k, dst=None, borderType=None)
"""
cornerHarris参数:
	src       - 数据类型为 float32 的输入图像。(输入单通道图)
	blockSize - 角点检测中要考虑的领域大小。也就是计算协方差矩阵时的窗口大小
	ksize     - Sobel求导中使用的窗口大小
	k         - Harris 角点检测方程中的自由参数,取值参数为 [0.04,0.06].
	dst       - 输出图像
	borderType  - 边界的类型
"""

示例一:

# encoding:utf-8
import cv2
import numpy as np

filename = 'D:\image_person\00001.png'

img = cv2.imread(filename)
img = cv2.resize(img, (640, 480))

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)

# 输入图像必须是float32, 最后一个参数[0.04,0.06]
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
cv2.imshow('dst', dst)
dst = cv2.dilate(dst, None)

img[dst > 0.01 * dst.max()] = [0, 0, 255]
cv2.imshow('img', img)
cv2.imshow('dst2', dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

左侧为原图,右侧为检测之后的图像。
在这里插入图片描述
参数测试:(我写了两组数据测试,使大家一目了然,BlockSize ,Ksize 这两个参数的含义)

import cv2
import numpy as np


img = cv2.imread('D:\image_person\06_01.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

gray = np.float32(gray)                 # cornerHarris函数图像格式为 float32

BlockSize =(2,3,4,5,7,9)
Ksize =(3,5,5,9,11,23)

for i,j in zip(BlockSize,Ksize):
    dst = cv2.cornerHarris(src=gray, blockSize=i, ksize=j, k=0.04)
    # 变量a的阈值为0.01 * dst.max(),如果dst的图像值大于阈值,那么该图像的像素点设为True,否则为False
    # 将图片每个像素点根据变量a的True和False进行赋值处理,赋值处理是将图像角点勾画出来
    a = dst>0.01 * dst.max()
    img[a] = [0, 0, 255]
    cv2.imshow('corners_' + str(i) + '_' + str(j), img)
    cv2.waitKey(0)           # 按Esc查看下一张

cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

有时候我们检验时有很多角点都是粘连在一起的,通过加入非极大值抑制来进一步去除一些粘在一起的角点。也就是在一个窗口内,如果有多个角点则用值最大的那个角点,其他的角点都删除。
请看如下示例:

import cv2
import numpy as np

img = cv2.imread('./lou.png')
cv2.imshow('raw_img', img)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)                 # cornerHarris函数图像格式为 float32

J = (0.05,0.01,0.005)
for j in J:    # 遍历设置阈值:j * dst.max()
    dst = cv2.cornerHarris(src=gray, blockSize=5, ksize=7, k=0.04)
    a = dst>j * dst.max()
    img[a] = [0, 0, 255]
    cv2.imshow('corners_'+ str(j), img)
    cv2.waitKey(0)           # 按Esc查看下一张

cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

二、Shi-Tomasi 角点检测 goodFeaturesToTrack()

goodFeaturesToTrack()是cornerHarris() 函数升级版。该函数的角点检测效果与cornerHarris()函数效果差不多。
Harris 角点检测的打分公式为:
R=λ1λ2k(λ1+λ2)2R =λ_1λ_2-k(λ_1+λ_2)^2

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/wsp_1138886114/article/details/90415190
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢