Opencv之Harris角点检测

Harris角点检测的目的是去分辨出图像中的平面、边界以及角点。

在这里插入图片描述

基本原理

下面三张图分别代表平面、边缘以及角点。
在这里插入图片描述人眼对角点的识别通常是在一个局部的小区域或小窗口完成的。如果在各个方向上移动这个特征的小窗口,窗口内区域的灰度发生了较大的变化,那么就认为在窗口内遇到了角点。如果这个特定的窗口在图像各个方向上移动时,窗口内图像的灰度没有发生变化,那么窗口内的图像就可能是一个平面;如果窗口在某一个方向移动时,窗口内图像的灰度发生了较大的变化,而在另一些方向上没有发生变化,那么,窗口内的图像可能就是一条直线的线段。
对于图像 I ( x , y ) I_{(x, y)} ,当点 ( x , y ) (x, y) 平移了 ( Δ x , Δ y ) (\Delta x, \Delta y) 之后,其自适应性为:
c ( x , y ; Δ x , Δ y ) = ( u , v ) W ( x , y ) ω ( u , v ) ( I ( u , v ) I ( u + Δ x , v + Δ y ) ) 2 c_{(x, y; \Delta x, \Delta y)} = \sum_{(u, v)\in W_{(x, y)}}{\omega_{(u, v)}(I_{(u, v)}-I_{(u+\Delta x, v+\Delta y)})^2}
其中 W ( x , y ) W_{(x, y)} 是以点 ( x , y ) (x, y) 为中心的窗口,通常取 3 × 3 3\times3 的窗口尺寸, ω ( u , v ) \omega_{(u, v)} 是此窗口上对应的每个点 ( u , v ) (u, v) 的权重,可以是常数,也可以是高斯加权函数。
I ( u + Δ x , v + Δ y ) I_{(u+\Delta x, v+\Delta y)} 进行一阶泰勒展开,得到:
I ( u + Δ x , v + Δ y ) = I ( u , v ) + I u ( u , v ) Δ x + I v ( u , v ) Δ y + O ( Δ x 2 , Δ y 2 ) I ( u , v ) + I u ( u , v ) Δ x + I v ( u , v ) Δ y I_{(u+\Delta x, v+\Delta y)}=I_{(u, v)}+I_{u(u, v)}\Delta x+I_{v(u, v)}\Delta y+O({\Delta x}^2, {\Delta y}^2)\approx I_{(u, v)}+I_{u(u, v)}\Delta x+I_{v(u, v)}\Delta y
近似可得:
c ( x , y ; Δ x , Δ y ) = ( u , v ) W ( x , y ) ω ( u , v ) ( I u ( u , v ) Δ x + I v ( u , v ) Δ y ) 2 c_{(x, y; \Delta x, \Delta y)} = \sum_{(u, v)\in W_{(x, y)}}{\omega_{(u, v)}(I_{u(u, v)}\Delta x+I_{v(u, v)}\Delta y)^2}
因为根据二次型转换,有:
c ( x , y ; Δ x , Δ y ) = [ Δ x Δ y ] M ( u , v ) [ Δ x Δ y ] c_{(x, y; \Delta x, \Delta y)} = \begin{bmatrix} \Delta x & \Delta y \end{bmatrix} M_{(u, v)} \begin{bmatrix} \Delta x \\ \Delta y \end{bmatrix}
其中,
M ( u , v ) = ( u , v ) W ( x , y ) ω ( u , v ) [ I u ( u , v ) 2 I u ( u , v ) I v ( u , v ) I u ( u , v ) I v ( u , v ) I v ( u , v ) 2 ] = [ ( u , v ) W ( x , y ) ω ( u , v ) I u ( u , v ) 2 ( u , v ) W ( x , y ) ω ( u , v ) I u ( u , v ) I v ( u , v ) ( u , v ) W ( x , y ) ω ( u , v ) I u ( u , v ) I v ( u , v ) ( u , v ) W ( x , y ) ω ( u , v ) I v ( u , v ) 2 ] = [ A C C B ] M_{(u, v)}=\sum_{(u, v)\in W_{(x, y)}} \omega_{(u, v)}\begin{bmatrix} {I_{u(u, v)}}^2 & I_{u(u, v)}I_{v(u, v)} \\ I_{u(u, v)}I_{v(u, v)} & {I_{v(u, v)}}^2 \end{bmatrix} = \begin{bmatrix} \mathop{\sum}\limits_{(u, v)\in W_{(x, y)}}\omega_{(u, v)}{I_{u(u, v)}}^2 & \mathop{\sum}\limits_{(u, v)\in W_{(x, y)}}\omega_{(u, v)}I_{u(u, v)}I_{v(u, v)} \\ \mathop{\sum}\limits_{(u, v)\in W_{(x, y)}}\omega_{(u, v)}I_{u(u, v)}I_{v(u, v)} & \mathop{\sum}\limits_{(u, v)\in W_{(x, y)}}\omega_{(u, v)}{I_{v(u, v)}}^2 \end{bmatrix}=\begin{bmatrix} A & C \\ C & B \end{bmatrix}
[ A C C B ] \begin{bmatrix} A & C \\ C & B \end{bmatrix} 对角化过后,会得到:
[ A C C B ] = R 1 [ λ 1 0 0 λ 2 ] R \begin{bmatrix} A & C \\ C & B \end{bmatrix} = R^{-1}\begin{bmatrix} \lambda_1 & 0\\ 0 & \lambda_2 \end{bmatrix} R
由于忽略余项之后的表达式为一个二项式函数,然而二项式函数的本质上就是一个椭圆函数,椭圆的扁率和尺寸是由M(x,y)的特征值λ1、λ2决定的,椭圆的方向是由M(x,y)的特征矢量决定的,如下图所示,椭圆方程为:
[ Δ x Δ y ] M ( x , y ) [ Δ x Δ y ] = 1 \begin{bmatrix} \Delta x & \Delta y \end{bmatrix} M_{(x, y)} \begin{bmatrix} \Delta x \\ \Delta y \end{bmatrix} =1
在这里插入图片描述椭圆函数特征值与图像中的角点、直线(边缘)和平面之间的关系如下图所示。共可分为三种情况:

a. 图像中的直线。一个特征值大,另一个特征值小,λ1>λ2或λ2>λ1。自相关函数值在某一方向上大,在其他方向上小。

b. 图像中的平面。两个特征值都小,且近似相等;自相关函数数值在各个方向上都小。

c. 图像中的角点。两个特征值都大,且近似相等,自相关函数在所有方向都增大。
在这里插入图片描述由于我们是通过M的两个特征值的大小对图像进行分类,所以,定义角点响应R值:
R = d e t M α ( t r a c e M ) R = detM-\alpha(traceM)
其中, d e t M = λ 1 λ 2 detM=\lambda_{1}\lambda_{2} 以及 t r a c e M = λ 1 + λ 2 traceM=\lambda_{1}+\lambda_{2}
所以,上图可以转化为:
在这里插入图片描述

用python实现Harris角点检测

import cv2 
import numpy as np

img = cv2.imread('box.png')
print ('img.shape:',img.shape)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)  # 计算角点相应R值
print ('dst.shape:',dst.shape)
img[dst>0.1*dst.max()]=[0,0,255]  # 认为角点相应R值大于某值时为角点
cv2.imshow('dst',img) 
cv2.waitKey(0) 
cv2.destroyAllWindows()

得到的结果为:
原图像:
在这里插入图片描述
标出角点后的图像:
在这里插入图片描述

发布了36 篇原创文章 · 获赞 1 · 访问量 538

猜你喜欢

转载自blog.csdn.net/qq_36758914/article/details/104017341