第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > OpenCV 图像特征提取——Harris角点检测

OpenCV 图像特征提取——Harris角点检测

时间:2022-01-23 08:05:33

相关推荐

OpenCV 图像特征提取——Harris角点检测

OpenCV 图像特征提取

Harris 角点检测

文章目录

1、什么是角点2、如何区分角点、边界和平面3、角点公式推导4、OpenCV相关函数5、角点检测程序实现最后

1、什么是角点

同角点并列的还有边界点、平面点。看下面的图可以看出来三者之间的位置关系。

从上面的图片我们可以看出来:

平面:A, B边界:C, D角点:E, F

简化一点就是下面三种情况:

2、如何区分角点、边界和平面

我们使用肉眼观察很方便,但是输入到计算机里面就需要相应的算法进行识别。

平面:之所以叫平面,是因为在图像窗口任意移动过程中,像素值不会发生明显的变化,趋于平滑。

边界:当图像窗口在边界范围移动时,像素值会沿一个方向基本不变,在垂直的方向发生巨大变化。可以看中间的图片,当沿 y 轴运动时,像素值不会发生大的变化。当沿 x 轴移动时会发生像素值会发生巨大变化。

角点:不同于平面和边界,图像窗口处于角点位置时,沿任意方向都会发生巨大变化。

利用上面的规则我们就可以区分角点、边界和平面。

3、角点公式推导

我们在实际中主要是观察移动前后像素值的变化情况。

1、当图像在 ( x , y ) (x, y) (x,y) 处平移 ( Δ x , Δ y ) (\Delta x, \Delta y) (Δx,Δy) 后的自相似性:

c ( x , y ; Δ x , Δ y ) = ∑ u , v ∈ W ( x , y ) w ( 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)}w(u,v)(I(u,v)-I(u+\Delta x, v+\Delta y))^2 c(x,y;Δx,Δy)=u,v∈W(x,y)∑​w(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) 为中心的窗口,这里既可以取常数,或者是高斯加权的函数(推荐)。

2、对上面的部分式子进行化简,泰勒展开:

I ( u + Δ x , v + Δ y ) = I ( u , v ) + I x ( u , v ) Δ x + I y ( u , v ) Δ y + O ( Δ x 2 , Δ y 2 ) ≈ I ( u , v ) + I x ( u , v ) Δ x + I y ( u , v ) Δ y I(u+\Delta x, v+\Delta y)=I(u,v)+I_x(u,v)\Delta x + I_y(u,v)\Delta y + O(\Delta x^2, \Delta y^2) \approx I(u,v)+ I_x(u, v)\Delta x + I_y(u,v)\Delta y I(u+Δx,v+Δy)=I(u,v)+Ix​(u,v)Δx+Iy​(u,v)Δy+O(Δx2,Δy2)≈I(u,v)+Ix​(u,v)Δx+Iy​(u,v)Δy

其中 I x , I y I_x,I_y Ix​,Iy​ 分别是 x , y x, y x,y 的偏导数。

3、进一步化简关于 c 的方程,近似可得:

c ( x , y ; Δ x , Δ y ) ≈ ∑ w ( I x ( u , v ) Δ x + I y ( u , v ) Δ y ) 2 = [ Δ x , Δ y ] M ( x , y ) [ Δ x Δ y ] c(x,y;\Delta x,\Delta y) \approx\sum_w (I_x(u, v)\Delta x + I_y(u,v)\Delta y)^2 = [\Delta x , \Delta y]M(x,y)\begin{bmatrix} \Delta x \\ \Delta y \end{bmatrix} c(x,y;Δx,Δy)≈w∑​(Ix​(u,v)Δx+Iy​(u,v)Δy)2=[Δx,Δy]M(x,y)[ΔxΔy​]

我们发现上卖弄的式子是一个平方项,我们可以使用二次型对结果进行化简,提取二次型矩阵。

4、二次型矩阵

M ( x , y ) = ∑ w [ I x ( x , y ) 2 I x ( x , y ) I y ( x , y ) I x ( x , y ) I y ( x , y ) I y ( x , y ) 2 ] = [ ∑ w I x ( x , y ) 2 ∑ w I x ( x , y ) I y ( x , y ) ∑ w I x ( x , y ) I y ( x , y ) ∑ w I y ( x , y ) 2 ] = [ A B B C ] M(x, y) = \sum_w\begin{bmatrix} I_x(x,y)^2 & I_x(x, y)I_y(x, y) \\ I_x(x, y)I_y(x, y) & I_y(x, y)^2 \end{bmatrix} = \begin{bmatrix} \sum_w I_x(x,y)^2 & \sum_w I_x(x,y)I_y(x,y)\\ \sum_w I_x(x,y)I_y(x,y) & \sum_w I_y(x,y)^2 \end{bmatrix}=\begin{bmatrix} A & B \\ B & C \end{bmatrix} M(x,y)=w∑​[Ix​(x,y)2Ix​(x,y)Iy​(x,y)​Ix​(x,y)Iy​(x,y)Iy​(x,y)2​]=[∑w​Ix​(x,y)2∑w​Ix​(x,y)Iy​(x,y)​∑w​Ix​(x,y)Iy​(x,y)∑w​Iy​(x,y)2​]=[AB​BC​]

化简可得:

c ( x , y ; Δ x , Δ y ) ≈ A Δ x 2 + 2 C Δ x Δ y + B Δ y 2 c(x,y;\Delta x,\Delta y) \approx A\Delta x^2+2C\Delta x \Delta y + B \Delta y^2 c(x,y;Δx,Δy)≈AΔx2+2CΔxΔy+BΔy2

{ A = I x 2 B = I x I y C = I y 2 \begin{cases} A=I_x^2\\ B=I_x I_y\\ C=I_y^2 \end{cases} ⎩⎪⎨⎪⎧​A=Ix2​B=Ix​Iy​C=Iy2​​

5、形状估计

我们可以看得出来二次项函数是一个椭圆函数,类似于: x 2 a 2 + y 2 b 2 = c \frac{x^2}{a^2}+\frac{y^2}{b^2} = c a2x2​+b2y2​=c,只不过是一个不过圆心的椭圆函数。

而且椭圆的大小随着 Δ x , Δ y \Delta x , \Delta y Δx,Δy的变化而变化。类似于一个锥体。

我们最后希望检测角点,我们上面提到,它的变化越大,说明是角点的可能性越大。也就是说在单位 Δ x , Δ y \Delta x , \Delta y Δx,Δy变化中,角点所在位置一般就是$A, B, C $较大值的点。实际中我们并不好利用三个值来进行判断是否是边界,平面还是角点。所以我们根据性质来减少自变量

6、减少自变量

根据我们之前学的高数,里面有一个定理:

实对称矩阵一定可以对角化

我们的 M M M 矩阵是一个实对称矩阵( M T = M M^T = M MT=M ),那么它一定可以对角化,并且一定存在一组特征值( λ 1 , λ 2 \lambda_1, \lambda_2 λ1​,λ2​ ),那么就将矩阵对角化。这样自变量由三个变成了两个,我们就方便来区分三者。

从上图我们可以分析出来:

平面: λ 1 , λ 2 \lambda_1,\lambda_2 λ1​,λ2​均小,也就说梯度不怎么变化边界: λ 1 ≫ λ 2 , λ 1 ≪ λ 2 \lambda_1 \gg \lambda_2,\lambda_1 \ll \lambda_2 λ1​≫λ2​,λ1​≪λ2​,也就是说梯度只沿一个方向变化快,垂直方向变化慢。角点: λ 1 , λ 2 \lambda_1,\lambda_2 λ1​,λ2​ 均大,也就是沿任意方向变化均快。

7、角点响应值

上面我们只是分析了依靠 λ 1 , λ 2 \lambda_1,\lambda_2 λ1​,λ2​来区分三者,那么需要更加准确的表达式来进行判别。

R = d e t M − α ( t r a c e M ) 2 R=detM - \alpha(traceM)^2 R=detM−α(traceM)2

其中 d e t M = λ 1 λ 2 : 行 列 式 的 值 t r a c e M = λ 1 + λ 2 : 迹 detM = \lambda_1\lambda_2:行列式的值 \quad traceM=\lambda_1+\lambda_2:迹 detM=λ1​λ2​:行列式的值traceM=λ1​+λ2​:迹

4、OpenCV相关函数

cv2.cornerHarris(img, blockSize, ksize, k)

img:输入图像。类型为float32blockSize:角点检测中指定的区域大小ksize:Soble求导中使用窗口的大小k:取值为[0.04-0.06]

5、角点检测程序实现

程序实现:

def cv_show(src):cv2.imshow('',src) cv2.waitKey(0) cv2.destroyAllWindows()img_copy = img.copy()img = cv2.imread('Pic/check.jpg') # 棋盘图片gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度图dst = cv2.cornerHarris(gray, 2, 3, 0.04) # 角点检测img[dst>0.0005*dst.max()]=[0,0,255] # 标记角点res = np.hstack((img_copy, img))cv_show(res)

结果如下:

最后

更多精彩内容,大家可以转到我的主页:曲怪曲怪的主页

或者关注我的微信公众号:TeaUrn

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。