1.Harris角点检测
import numpy as np
import cv2 as cv
import matplotlib. pyplot as plt
plt. rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]
'''
Harris角点检测的思想是通过图像的局部小窗口观察图像,角点的特征是窗口沿任意方向移动都会导致
图像灰度的明显变化
将上述思想转化为数学表达式,即将局部窗口向各个方向移动(u,v)并计算所有灰度差异的总和,表达式
如下:
E(u,v)=∑w(x,y)[I(x+u,y+v)-I(x,y)]²
其中I(x,y)是局部窗口的灰度图,I(x+u,y+v)是平移后的灰度图像,w(x,y)是窗口函数,其可以是矩形
窗口,也可以是对每一个像素赋予不同权重的高斯窗口
角点检测中使E(u,v)的值最大.利用一阶泰勒展开有:
I(x+u,y+v)=I(x,y)+Ix*u+Iy*v
其中:Ix和Iy是沿x和y方向的导数,可用sobel算子计算.
E(u,v)=∑w(x,y)[I(x+u,y+v)-I(x,y)]²
=∑w(x,y)[Ix²u²+2Ix*Iy*u*v+Iy²*v²]
|Ix² Ix*Iy|
=∑w(x,y)[u,v]|Ix*Iy Iy²|
=[u v]M|u|
|v|
M矩阵决定了E(u,v)的取值,M是Ix和Iy的二次函数,可以表示成椭圆的形状,椭圆的长短半轴由M的特征
值a1和a2决定,方向由特征矢量决定
共可分为三种情况:
.图像中的直线.一个特征值大,另一个特征值小,a1>>a2或者a2>>a1.椭圆函数值在某一个方向上大,
在其他方向小
.图像中的平面.两个特征值都小,且近似相等,椭圆函数值再各个方向都有
.图像中的角点.两个特征值都大,且近似相等,椭圆函数在所有方向都增大.
Harris给出的角点计算方法并不需要计算具体的特征值,而是计算一个角点响应值R来判断角点.R的计算公式
为:
R=detM-α(traceM)²
式中,detM为矩阵M的行列式,traceM为矩阵M的迹,α为常数取值范围为0.04~0.06.事实上,特征是隐含
在detM和traceM中,因为:
detM=a1a2
traceM=a1+a2
那么认为:
.当R为大数时的正数是角点
.当R为大数时的负数为边界
.当R为小数认为是平坦区域
API:
cv.cornerHarris(src,blockSize,ksize,k)
参数:
img:数据类型为float32的输入图像
blockSize:角点检测中要考虑的领域大小
ksize:sobel算子求导使用的核大小
k:角点检测中的自由参数取值范围为[0.04,0.06]
'''
img = cv. imread( 'image/house.jpg' )
gray = cv. cvtColor( img, cv. COLOR_BGR2GRAY)
gray_float32 = np. float32( gray)
dst = cv. cornerHarris( gray_float32, 2 , 3 , 0.04 )
R= dst. max ( ) * 0.01
img[ dst > R] = [ 0 , 0 , 255 ]
plt. subplot( 2 , 2 , 1 )
plt. imshow( cv. imread( 'image/house.jpg' ) [ : , : , : : - 1 ] )
plt. title( '原图' )
plt. subplot( 2 , 2 , 2 )
plt. imshow( gray, cmap= plt. cm. gray)
plt. title( '灰度图(uint8型)' )
plt. subplot( 2 , 2 , 3 )
plt. imshow( gray_float32, cmap= plt. cm. gray)
plt. title