图像特征学习笔记 Harris角点检测 原理和程序

图像特征学习——Harris角点检测(opencv-python)

本项目理论和源代码来自唐宇迪opencv项目实战


1 概述

图像的特征提取

一张图片中我们进行特征提取,主要分为平坦区域、边界区域和角点区域。本项目依据这三种类型的特征展开Harris角点检测的探究。
文末附代码

2 理论背景

Harris角点检测

如何分辨图像中的三中特征:角点、平坦区域、边界。
在图像中框出一个窗口,并在图像上小范围移动(△x,△y),计算移动前窗口图像的相关性。
图像特征学习笔记 Harris角点检测 原理和程序_第1张图片
自相关性表示为:
在这里插入图片描述
这一步在cv2.cornerHarris()函数中体现为第二个参数,表示窗口的大小。
从自相关性表达式中可以看出:该值越大,说明移动前后灰度变化越大;该值越小,说明移动前后灰度变化越小
特别的,我们更关注的是窗口内图像的中心部分。在自相关性的表达式中,增加了权值W(u, v),这个权值可以是常数也可以是高斯加权函数,高斯加权函数最常使用。
平方项中前一项是原窗口中(u,v)像素点的灰度值,后一项是移动后窗口中(u+△x+v+△y)像素点处的灰度值。
对每一个像素点都要进行计算,那么就需要对表达式进行简化。
基于泰勒展开式,对平方项中的后一项进行化简:
在这里插入图片描述代入自相关性的表达式中,第一项消掉。其中Ix和Iy是偏导数。
近似得到:
在这里插入图片描述
将这个近似的表达式转化成三个矩阵的乘积。利用矩阵求出特征值。线性代数中特征值的分解,是将一个矩阵分解为如下形式
图像特征学习笔记 Harris角点检测 原理和程序_第2张图片
最后自相关性可以表达为:
在这里插入图片描述
其中M(x, y)相当于特征值分解中的∑
求出M(x, y):
在这里插入图片描述
矩阵的副对角线相同,M(x, y)可以简化表示为:
在这里插入图片描述
由于M(x, y)是一个2行2列的实对称矩阵,所以可以求出矩阵的两个特征值λ1、λ2。用A,B,C表示自相关性:
在这里插入图片描述
其中
在这里插入图片描述
而二次项的表达式本质上可以看成是椭圆的解析式!
线性相关性的椭圆表达式为:
在这里插入图片描述
令表达式等于1,得到:
在这里插入图片描述
再回来看化简后的矩阵:
在这里插入图片描述
能转化成以λ1,λ2为主对角线的矩阵。
λ1 △x^2+λ2 △y ^2=1
和椭圆表达式对比:
在这里插入图片描述
a=λ1^(-1/2)
b =λ2^(-1/2)
图像特征学习笔记 Harris角点检测 原理和程序_第3张图片

λ值越大,自相关性的表达式的值越大,说明像素灰度值变化越大。
λ值越小,自相关性的表达式的值越小,说明像素灰度值变化越小。

3 结论

边界 一个特征值大,一个特征值小 ,λ1>>λ2或者λ1<<λ2,自相关函数在某一个方向上大,在另一个方向上小
平坦 两个特征值都小,且近似相等,自相关函数在各个方向上都小
角点 两个特征值都大,且近似相等,自相关函数在所有方向都增大

为便于表示,用角点响应R值来代替比较λ1,λ2的方法作为评价指标。
R = det M - α(trace M)^2
其中:det M = λ1*λ2, trace M = λ1+λ2, α是一个系数,通常设为(0.04, 0.06

R<0 边界
R≈0 平坦区
R>0 角点

总结一下harris角点检测算法的基本流程

  1. 计算梯度Ix(u, v), Iy(u,v)在程序中用Sobel算子计算梯度。
  2. 整合成一个矩阵,
    在这里插入图片描述
    并求出矩阵的特征值λ1, λ2.
  3. 比较特征值得大小做出判断。
  4. 非极大值抑制,确定角点(非极大值抑制在Canny边缘检测中也用到过)

以上是Harris角点检测算法的原理,代码如下

4 代码

import cv2
import numpy as np

img = cv2.imread('test_1.jpg')
print('img.shape:', img.shape)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
print('dst.shape:',dst.shape)
img[dst > 0.01*dst.max()] = [0,0,255]
cv2.imshow('dst', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.cornerHarris()函数对输入图像的要求是数据类型为 float32 的入图像
先将图像转化为灰度图,对于特殊格式的图像还要用np.float32()进一步转化。
cv2.cornerHarris()函数的第二个参数是2,表示窗口的大小。
cv2.cornerHarris()函数的第三个参数是3,表示Sobel算子的大小。还记得之前说过Sobel是干嘛用的吗--------计算梯度Ix(u, v), Iy(u, v)
Sobel算子模板如图所示:
图像特征学习笔记 Harris角点检测 原理和程序_第4张图片
Sobel是计算机视觉中经典的边缘检测算法,两个算子分别用来检测水平方向和垂直方向的边缘。在技术上,Sobel算子是离散性差分算子,用来运算图像亮度函数的梯度之近似值

cv2.cornerHarris()函数的第四个参数设置成0.04,就是角点响应R值中的系数。
发现没有,前半节讲解的所有原理都封装在这一条函数里了:)
下一条语句非极大值抑制,大于最大值的1%则看做是角点,画出来。
显示结果:
图像特征学习笔记 Harris角点检测 原理和程序_第5张图片

至此,Harris角点检测项目完成。
感谢为我提供帮助的博客,你的辛勤耕耘让我受益匪浅。

果然漂亮的人五官都是棱角分明的
图像特征学习笔记 Harris角点检测 原理和程序_第6张图片
嗯!棱角分明…
遇到中意的姑娘先给她角点检测一下,希望你已经找到了那个姑娘。

你可能感兴趣的:(图像特征学习笔记 Harris角点检测 原理和程序)