图像特征检测——Harris角点检测

图像特征检测——Harris角点检测

一、Harris角点检测

(1)原理
通过一个小窗口对图像进行积分,随着窗口的移动,根据窗口内像素灰度积分值来判断像素点是否为角点,依据如下:

  • 灰度变化平缓的地方,窗口向任何方向移动,灰度积分保持不变,定义为“flat”
  • 图像边缘区域,窗口沿着边缘移动时,灰度积分近似不变,沿着其他方向移动时,灰度积分变化剧烈,定义为“edge”
  • 在角点处,窗口向任何方向移动,灰度积分都会剧烈变化,定义为“corner”

图像特征检测——Harris角点检测_第1张图片
(2)灰度积分变化
定义灰度积分变化为 E ( u , v ) = Σ w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] 2 E(u,v) = \Sigma w(x, y)[I(x+u,y+v)-I(x, y)]^2 E(u,v)=Σw(x,y)[I(x+u,y+v)I(x,y)]2其中

Σ [ I ( x + u , y + v ) − I ( x , y ) ] 2 ≈ Σ [ I ( x , y ) + u I x + v I y − I ( x , y ) ] \Sigma [I(x+u,y+v)-I(x, y)]^2\approx \Sigma [I(x, y)+uI_x+vI_y-I(x,y)] Σ[I(x+u,y+v)I(x,y)]2Σ[I(x,y)+uIx+vIyI(x,y)]

= Σ u 2 I x 2 + 2 u v I x I y + v 2 I y 2 =\Sigma u^2I_x^2+2uvI_xI_y+v^2I_y^2 =Σu2Ix2+2uvIxIy+v2Iy2

= Σ [ u v ] [ I x 2 I x I y I x I y I y 2 ] [ u v ] =\Sigma \left[ \begin{matrix} u & v \end{matrix}\right] \left[ \begin{matrix} I_x^2 & I_xI_y \\ I_xI_y & I_y^2 \end{matrix}\right] \left[ \begin{matrix} u \\ v \end{matrix}\right] =Σ[uv][Ix2IxIyIxIyIy2][uv]

= [ u v ] ( Σ [ I x 2 I x I y I x I y I y 2 ] ) [ u v ] =\left[ \begin{matrix} u & v \end{matrix}\right] (\Sigma \left[ \begin{matrix} I_x^2 & I_xI_y \\ I_xI_y & I_y^2 \end{matrix}\right] ) \left[ \begin{matrix} u \\ v \end{matrix}\right] =[uv](Σ[Ix2IxIyIxIyIy2])[uv]
当窗口移动的距离很小的时候,即 ( u , v ) (u,v) (u,v)的变换很小,则有
E ( u , v ) = [ u v ] M [ u v ] E(u,v) = \left[ \begin{matrix} u & v \end{matrix}\right] M \left[ \begin{matrix} u \\ v \end{matrix}\right] E(u,v)=[uv]M[uv]其中, M = Σ w ( x , y ) [ I x 2 I x I y I x I y I y 2 ] M = \Sigma w(x,y)\left[ \begin{matrix} I_x^2 & I_xI_y \\ I_xI_y & I_y^2 \end{matrix}\right] M=Σw(x,y)[Ix2IxIyIxIyIy2]
可以发现, E E E是一个二次型,可以化简为 E = [ u v ] [ A C C B ] [ u v ] = A u 2 + B v 2 + 2 C u v E= \left[ \begin{matrix} u & v \end{matrix}\right] \left[ \begin{matrix} A & C \\ C & B\end{matrix}\right] \left[ \begin{matrix} u \\ v \end{matrix}\right] = Au^2+Bv^2+2Cuv E=[uv][ACCB][uv]=Au2+Bv2+2Cuv
等效为椭圆模型,则为
u 2 / a 2 + v 2 / b 2 = 1 u^2/a^2+v^2/b^2=1 u2/a2+v2/b2=1
图像特征检测——Harris角点检测_第2张图片
(3)Harris算子

λ 1 − 1 / 2 \lambda_1^{-1/2} λ11/2 λ 2 − 1 / 2 \lambda_2^{-1/2} λ21/2是椭圆的长短轴

  • λ 1 和 λ 2 \lambda_1和\lambda_2 λ1λ2都比较小时,点 ( x , y ) (x,y) (x,y)处于“flat”区域.
  • λ 1 > > λ 2 \lambda_1>>\lambda_2 λ1>>λ2或者 λ 1 < < λ 2 \lambda_1<<\lambda_2 λ1<<λ2时,点 ( x , y ) (x,y) (x,y)处于“edge”区域.
  • λ 1 和 λ 2 \lambda_1和\lambda_2 λ1λ2都比较大时,点 ( x , y ) (x,y) (x,y)为“orner”.

(4)角点响应函数
上一点说的 λ 1 和 λ 2 \lambda_1和\lambda_2 λ1λ2比较小和比较大是一个相对值,在实际检测中是无法有效界定的,因此,Harris算子引入角点响应函数来判断像素点的类型
R = d e t M − k ( t r a c e M ) 2 R = detM-k(traceM)^2 R=detMk(traceM)2 t r a c e M = λ 1 + λ 2 trace M = \lambda_1+\lambda_2 traceM=λ1+λ2 d e t M = λ 1 λ 2 det M = \lambda_1\lambda_2 detM=λ1λ2

  • R R R接近于零时,处于灰度变化平缓的“flat”区域
  • R < 0 R<0 R<0时,点为边缘“edge”像素
  • R > 0 R>0 R>0时,点为角点“corner”

(5)opencv Harris角点检测函数

C++:
void cv::cornerHarris	(	InputArray 	src,			# 输入图像,单通道-8位或者浮点型图像
				OutputArray 	dst,		# 输出图像,保存Harris角点检测结果,和源图像尺寸一样
				int 	blockSize,				# 邻域的大小
				int 	ksize,						# Sobel算子的孔径大小
				double 	k,					# 角点响应函数的参数k
				int 	borderType = BORDER_DEFAULT 		# 图像像素的边界模式
				)	
	
Python:
dst	=	cv.cornerHarris(	src, blockSize, ksize, k[, dst[, borderType]]	)

二、python实现Harris角点检测

import cv2 as cv
import numpy as np

# Harris method
lena = cv.imread("/home/lihoon/code/opencvImg/Harris/lena.jpg")
gray_lena = cv.cvtColor(lena, cv.COLOR_BGR2GRAY)
gray_lena = np.float32(gray_lena)

dst = cv.cornerHarris(gray_lena, 3, 3, 0.05)
lena[dst > 0.01 * dst.max()] = [0, 0, 255]

cv.imshow("Harris", lena)

cv.waitKey()

图中,红色的点就是通过Harris角点检测算子检测的特征点

图像特征检测——Harris角点检测_第3张图片

你可能感兴趣的:(OpenCV)