文章目录
- 原理
- 测试
原理
Harris 角点检测的基本思路如下:考虑一个局部的区域,将其作为一个窗口四处移动,若窗口灰度发生了较大的变化,那么,就认为窗口内存在角点,否则窗口内就不存在角点。
对于图像 I ( p ⃗ ) I(\vec p) I(p),当在点 p ⃗ = ( x , y ) \vec p=(x,y) p=(x,y)处平移 Δ p ⃗ = ( Δ x , Δ y ) \Delta\vec p=(\Delta x, \Delta y) Δp=(Δx,Δy)后的自相似性,可以通过下面的自相关函数给出
S W ( Δ x , Δ y ) = ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) ( I ( p ⃗ i + Δ p ⃗ ) − I ( p ⃗ i ) ) 2 S_W(\Delta x, \Delta y)=\sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)(I(\vec p_i + \Delta\vec p)-I(\vec p_i))^2 SW(Δx,Δy)=xi∈W∑yi∈W∑w(pi)(I(pi+Δp)−I(pi))2
其中, W W W是以点 ( x , y ) (x,y) (x,y)为中心的窗口, w ( p ⃗ i ) w(\vec p_i) w(pi)是点 p ⃗ i \vec p_i pi处的加权函数,一般取高斯函数 e − ( x i − x ) 2 + ( y i − y ) 2 2 σ 2 e^{-\frac{(x_i-x)^2+(y_i-y)^2}{2\sigma^2}} e−2σ2(xi−x)2+(yi−y)2。当 Δ p ⃗ \Delta\vec p Δp取不同值时,若 S W S_W SW都有较大变化,则可认为 p ⃗ \vec p p是一个角点,此即Harris角点检测的基本思路。
对平移后的图像进行泰勒展开,可得
I ( p ⃗ i + Δ p ⃗ ) ≈ I ( p ⃗ i ) + I x ( p ⃗ i ) Δ x + I y ( p ⃗ i ) Δ y I(\vec p_i+\Delta\vec p)\approx I(\vec p_i)+I_x(\vec p_i)\Delta x+I_y(\vec p_i)\Delta y I(pi+Δp)≈I(pi)+Ix(pi)Δx+Iy(pi)Δy
其中 I x , I y I_x, I_y Ix,Iy为偏导数,将其带入 S W S_W SW,有
S W ( Δ x , Δ y ) ≈ ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) ( I x ( p ⃗ i ) Δ x + I y ( p ⃗ i ) Δ y ) 2 = ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) [ I x 2 ( p ⃗ i ) Δ x 2 + I y 2 ( p ⃗ i ) Δ y 2 + 2 I x ( p ⃗ i ) I y ( p ⃗ i ) Δ x Δ y ] = ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) [ Δ x Δ y ] [ I x 2 ( p ⃗ i ) I x ( p ⃗ i ) I y ( p ⃗ i ) I x ( p ⃗ i ) I y ( p ⃗ i ) I y 2 ( p ⃗ i ) ] [ Δ x Δ y ] \begin{aligned} S_W(\Delta x, \Delta y)&\approx\sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)(I_x(\vec p_i)\Delta x+I_y(\vec p_i)\Delta y)^2\\ &=\sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)\left[I_x^2(\vec p_i)\Delta x^2+I_y^2(\vec p_i)\Delta y^2+2I_x(\vec p_i)I_y(\vec p_i)\Delta x\Delta y\right]\\ &=\sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)\begin{bmatrix}\Delta x&\Delta y\end{bmatrix}\begin{bmatrix} I_x^2(\vec p_i)&I_x(\vec p_i)I_y(\vec p_i)\\ I_x(\vec p_i)I_y(\vec p_i)&I_y^2(\vec p_i) \end{bmatrix}\begin{bmatrix}\Delta x\\ \Delta y\end{bmatrix}\\ \end{aligned} SW(Δx,Δy)≈xi∈W∑yi∈W∑w(pi)(Ix(pi)Δx+Iy(pi)Δy)2=xi∈W∑yi∈W∑w(pi)[Ix2(pi)Δx2+Iy2(pi)Δy2+2Ix(pi)Iy(pi)ΔxΔy]=xi∈W∑yi∈W∑w(pi)[ΔxΔy][Ix2(pi)Ix(pi)Iy(pi)Ix(pi)Iy(pi)Iy2(pi)][ΔxΔy]
将其记作
S W ( Δ x , Δ y ) = [ Δ x Δ y ] M ( x , y ) [ Δ x Δ y ] S_W(\Delta x, \Delta y)=\begin{bmatrix}\Delta x&\Delta y\end{bmatrix}M(x,y)\begin{bmatrix}\Delta x\\ \Delta y\end{bmatrix} SW(Δx,Δy)=[ΔxΔy]M(x,y)[ΔxΔy]
其中 M ( p ⃗ ) M(\vec p) M(p)只与当前点 p ⃗ \vec p p有关,可记作
M ( p ⃗ ) = ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) [ I x 2 ( p ⃗ i ) I x ( p ⃗ i ) I y ( p ⃗ i ) I x ( p ⃗ i ) I y ( p ⃗ i ) I y 2 ( p ⃗ i ) ] = [ ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) I x 2 ( p ⃗ i ) ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) I x ( p ⃗ i ) I y ( p ⃗ i ) ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) I x ( p ⃗ i ) I y ( p ⃗ i ) ∑ x i ∈ W ∑ y i ∈ W w ( p ⃗ i ) I y 2 ( p ⃗ i ) ] \begin{aligned} M(\vec p) &=\sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)\begin{bmatrix} I_x^2(\vec p_i)&I_x(\vec p_i)I_y(\vec p_i)\\ I_x(\vec p_i)I_y(\vec p_i)&I_y^2(\vec p_i) \end{bmatrix}\\ &=\begin{bmatrix} \sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)I_x^2(\vec p_i)& \sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)I_x(\vec p_i)I_y(\vec p_i)\\ \sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)I_x(\vec p_i)I_y(\vec p_i)& \sum_{x_i\in W}\sum_{y_i\in W}w(\vec p_i)I_y^2(\vec p_i) \end{bmatrix}\\ \end{aligned} M(p)=xi∈W∑yi∈W∑w(pi)[Ix2(pi)Ix(pi)Iy(pi)Ix(pi)Iy(pi)Iy2(pi)]=[∑xi∈W∑yi∈Ww(pi)Ix2(pi)∑xi∈W∑yi∈Ww(pi)Ix(pi)Iy(pi)∑xi∈W∑yi∈Ww(pi)Ix(pi)Iy(pi)∑xi∈W∑yi∈Ww(pi)Iy2(pi)]
M ( p ⃗ ) M(\vec p) M(p)有四项,可写作
M ( p ⃗ ) = [ A C C B ] M(\vec p)=\begin{bmatrix}A&C\\C&B\end{bmatrix} M(p)=[ACCB]
从而自相关函数可近似为
S W ( Δ x , Δ y ) ≈ [ Δ x Δ y ] [ A C C B ] [ Δ x Δ y ] = A Δ x 2 + 2 C Δ x Δ y + B Δ y 2 \begin{aligned} S_W(\Delta x, \Delta y)&\approx\begin{bmatrix}\Delta x&\Delta y\end{bmatrix}\begin{bmatrix}A&C\\C&B\end{bmatrix}\begin{bmatrix}\Delta x\\ \Delta y\end{bmatrix}\\ &=A\Delta x^2+2C\Delta x\Delta y+B\Delta y^2 \end{aligned} SW(Δx,Δy)≈[ΔxΔy][ACCB][ΔxΔy]=AΔx2+2CΔxΔy+BΔy2
以 Δ x , Δ y \Delta x, \Delta y Δx,Δy分别作为横轴与纵轴,则 A , B , C , S W A, B, C, S_W A,B,C,SW固定时,上式构成一个椭圆方程,其短轴和长轴分别为 S W λ M , S W λ m \sqrt{\frac{S_W}{\lambda_M}}, \sqrt{\frac{S_W}{\lambda_m}} λMSW,λmSW, λ M , λ m \lambda_M, \lambda_m λM,λm为 M ( p ⃗ ) M(\vec p) M(p)的大小两个特征值。
参数一经固定,那么 Δ x , Δ y \Delta x, \Delta y Δx,Δy就只能在椭圆上取值,才能使等式成立。而若换一种思路,点 Δ p ⃗ = ( Δ x , Δ y ) \Delta\vec p=(\Delta x, \Delta y) Δp=(Δx,Δy),将存在三种位置,即椭圆内部、椭圆上和椭圆外部。对于角点来说,应该让 Δ p ⃗ \Delta\vec p Δp挪动尽量小的情况下,从椭圆内部跳到椭圆外部,换言之,小窗移动因其较大变化。因此,椭圆的轴越短,则这种变化越明显。从而,当矩阵 M ( x ) M(x) M(x)的特征值较大时,可以认为 p ⃗ = ( x , y ) \vec p=(x,y) p=(x,y)是角点。
由于求特征值比较耗时,Harris定义了响应值 R R R
R = det M − k ( trace M ) 2 R=\det M-k(\operatorname{trace}M)^2 R=detM−k(traceM)2
其中trace表示迹,det为行列式, k k k为常数,一般取 0.04 → 0.06 0.04\to0.06 0.04→0.06。 R R R值与点的关系如下
- ∣ R ∣ \vert R\vert ∣R∣很小时,两个特征值都很小,对应区域为平面。
- R < 0 R<0 R<0时,两个特征值相差较大,对应区域为直线
- R R R较大时,两个特征值都很大,且近似相等,对应区域为角点。
测试
python-opencv中提供了Harris角点检测函数,其 R R R值计算结果以及角点检测结果如下
代码为
import cv2
import numpy as np
import matplotlib.pyplot as plt
path = 'lena.jpg'
img = plt.imread(path)
gray = img[:,:,0]
harris = cv2.cornerHarris(gray, 2, 3, 0.04)
fig = plt.figure()
ax = fig.add_subplot(121)
ax.imshow(harris)
ax = fig.add_subplot(122)
dst = cv2.dilate(harris, None) # 腐蚀harris结果
im1 = img + 0
im1[dst > 0.1 * dst.max()] = [255, 0, 0]
ax.imshow(im1)
plt.tight_layout()
plt.show()
【cornerHarris】即为harris角点计算函数,其输入的四个参数分别是待检测图像;角点检测时的移动范围;Sobel导数的尺寸(为奇数)以及 k k k值。