Opencv之Harris角点检测

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

在这里插入图片描述

基本原理

下面三张图分别代表平面、边缘以及角点。
在这里插入图片描述人眼对角点的识别通常是在一个局部的小区域或小窗口完成的。如果在各个方向上移动这个特征的小窗口,窗口内区域的灰度发生了较大的变化,那么就认为在窗口内遇到了角点。如果这个特定的窗口在图像各个方向上移动时,窗口内图像的灰度没有发生变化,那么窗口内的图像就可能是一个平面;如果窗口在某一个方向移动时,窗口内图像的灰度发生了较大的变化,而在另一些方向上没有发生变化,那么,窗口内的图像可能就是一条直线的线段。
对于图像 I ( x , y ) I_{(x, y)} I(x,y),当点 ( x , y ) (x, y) (x,y)平移了 ( Δ x , Δ y ) (\Delta x, \Delta y) (Δx,Δ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} c(x,y;Δx,Δy)=(u,v)W(x,y)ω(u,v)(I(u,v)I(u+Δx,v+Δy))2
其中 W ( x , y ) W_{(x, y)} W(x,y)是以点 ( x , y ) (x, y) (x,y)为中心的窗口,通常取 3 × 3 3\times3 3×3的窗口尺寸, ω ( u , v ) \omega_{(u, v)} ω(u,v)是此窗口上对应的每个点 ( 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 + Δ 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 I(u+Δx,v+Δy)=I(u,v)+Iu(u,v)Δx+Iv(u,v)Δy+O(Δx2,Δy2)I(u,v)+Iu(u,v)Δx+Iv(u,v)Δ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)=(u,v)W(x,y)ω(u,v)(Iu(u,v)Δx+Iv(u,v)Δ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} c(x,y;Δx,Δy)=[ΔxΔy]M(u,v)[ΔxΔy]
其中,
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} M(u,v)=(u,v)W(x,y)ω(u,v)[Iu(u,v)2Iu(u,v)Iv(u,v)Iu(u,v)Iv(u,v)Iv(u,v)2]=(u,v)W(x,y)ω(u,v)Iu(u,v)2(u,v)W(x,y)ω(u,v)Iu(u,v)Iv(u,v)(u,v)W(x,y)ω(u,v)Iu(u,v)Iv(u,v)(u,v)W(x,y)ω(u,v)Iv(u,v)2=[ACCB]
[ A C C B ] \begin{bmatrix} A & C \\ C & B \end{bmatrix} [ACCB]对角化过后,会得到:
[ 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 [ACCB]=R1[λ100λ2]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 [ΔxΔy]M(x,y)[ΔxΔy]=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) R=detMα(traceM)
其中, d e t M = λ 1 λ 2 detM=\lambda_{1}\lambda_{2} detM=λ1λ2以及 t r a c e M = λ 1 + λ 2 traceM=\lambda_{1}+\lambda_{2} traceM=λ1+λ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()

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cofisher

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值