本文是本人看bilibili教学结合官方文档的观后笔记,链接在下:
(全)基于python的Opencv项目实战_哔哩哔哩_bilibili
如果有什么理解不到位的地方,欢迎指正。
理论:
先放角点定义(百度百科):角点就是极值点,即在某方面属性特别突出的点。 当然,你可以自己定义角点的属性(设置特定熵值进行角点检测)。 角点可以是两条线的交叉处,也可以是位于相邻的两个主要方向不同的事物上的点。
opencv中的解释:corners are regions in the image with large variation in intensity in all the directions.
在图像上表现在:在不同的方向像素值有较大变化。
于是可以利用各个方向移动强度的不同,判断是否为角点,公式如下:
第一项为权值函数,可以为方形加权,也可以为高斯加权
第二项基于泰勒展开
其中:泰勒公式:
可以近似等于:
其中两个偏导数可以用梯度函数来计算,例如:cv.sobel()
公式容易得出为二次型,可以写为:
其中:
根据矩阵加法,将累加符换入矩阵中。
由数学定理可知:实对称矩阵必可以相似对角化。所以M中的矩阵可以化为对角矩阵:
其实是一个椭圆方程:
写为方程式:
所以:
当λ1与λ2都很大时,表示在U,V方向变化快速,应为角点。
故,可以用一个函数来说明图像特征关系,来自官方文档:
当|R|值很小,意味着:λ1与λ2都很小,检测点为flat
当R<0,意味着λ1>>λ2或者λ2>>λ1,检测点为边界
当R值很大,意味着:λ1与λ2都很大,且近似相等,检测点为角点
函数:
cornerHarris(img,blocksize,ksize,k)->dst
•dst - 返回一个单通道数组
• img - 数据类型为 float32 的输入图像。
• blockSize - 角点检测中指定区域小。
• ksize - Sobel 求导中使用的窗口大小
• k - 取值参数为 [0,04,0.06]
代码:
import cv2 as cv import numpy as np img = cv.imread("test_1.jpg" #需要传入灰度图像 grayimg = cv.cvtColor(img,cv.COLOR_BGR2GRAY) #返回的结果是一个单通道数组 grayimg = np.float32(grayimg) dst= cv.cornerHarris(grayimg,2,3,0.04) img[dst>0.01*dst.max()] = [0,0,255] cv.imshow("Harris corner",img) cv.waitKey()