• 图像特征(一)


    角点定义

    在之前的学习中,我们了解了图片有低频和高频两个主要成分,高频成分代表了图像的细节部分,其中,边缘就是典型的细节。今天我们要讲的角点,也属于细节的一种,严格的来说,角点会出现在图像边缘上。
    角点,顾名思义,就是图像中含有角度的边缘部分,比如这幅图中所注:
    在这里插入图片描述

    寻找角点

    知道了什么是角点,下一步我们要解决的问题就是用怎样的数学工具找到角点。首先我们观察角点低频色彩信息、边界和角点之间的区别。首先画出一个检测通道:
    在这里插入图片描述
    在图像的低频部分,我们的检测通道向四周移动时,由于通道周围的内容和通道内的内容相似度较高,因此通道内的数值不会有太大的变化。
    在这里插入图片描述
    图中,通道内的黑线为图像的边缘部分,它的特点是通道沿某个方向移动(如横向移动),通道内数值会产生明显差距,但沿另外的方向移动(如上下移动),通道值则不会产生明显差距。
    在这里插入图片描述
    如果通道包含了角点,那么通道移动过程中就会有多个方向会让通道值产生明显的变化(如上下和左上右下)。依据这样的特性,我们可以用这样的公式来描述通道移动过程中,值的变化和通道所处位置的关系:
    在这里插入图片描述
    W(x,y)是以(x,y)为中心的窗口函数,它反应了通道存储的值与原图对应像素的关系,它既可以是常数,也可以是高斯加权函数:
    在这里插入图片描述
    回到我们的C((x,y;△x,△y))函数,之所以加平方,是为了避免直接作差导致结果为负。我们暂时不考虑窗函数W,使用泰勒展开对图像I(x,y)在平移(△x,△y)后进行一阶近似:
    在这里插入图片描述
    将这个结果带到上式中,可以得到以下结果:
    在这里插入图片描述
    从C((x,y;△x,△y))的近似表达式可以看出,如果假设其值为1即:
    在这里插入图片描述

    这就是一个椭圆系,只是两个焦点不一定在坐标轴上。但M是一个实对称矩阵,因此一定可以相似对角化:
    在这里插入图片描述
    其中,λmax1/2代表椭圆的长半轴,λmin1/2代表了椭圆的短半轴,对角化后的椭圆焦点在坐标轴上:
    在这里插入图片描述
    这个分析结果在图像中没有实际意义,但我们可以把这个椭圆拉到一个新的直角坐标系里,就可以根据这个椭圆的形状来判断图像上该点是否为角点:当短半轴和长半轴差距很大,即椭圆越扁,说明窗口只在某一个方上向移动会导致通道值出现明显变化,即该区域为边缘;如果短半轴长半轴都很大且短半轴与长半轴差距不大,说明椭圆更像是半径很大的圆,这说明窗口在任何方向移动都可以导致通道值出现明显变化,该区域为角点;如果短半轴长半轴都较小且差距不大,椭圆更像半径很小的圆,这说明窗口在任意方向移动都不会导致通道值产生较大变化,该区域是平坦区。
    在这里插入图片描述
    大小关系是一个比较抽象的概念,具体描述还要引入一个新的概念:角点相应R
    在这里插入图片描述
    通过以上方式计算出的R值就可以具体描述三种关系了:R>0时,即为角点,R<0时为边界,R≈0为平坦区。当然还有一个问题,我们找到焦点之后,会发现角点附近的点也有着相似的R特征,为了过滤掉这些点,还需要加入非极大值抑制(NMS)。

    角点检测的OpenCV实现

    角点检测也有现成的函数:

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

    其中各参数的含义为

    • img: 输入图像,数据类型为 float32 的入图像;
    • blockSize:角点检测中指定区域的大小;
    • ksize:Sobel求导中使用的窗口大小,通常取3;
    • k:计算R值中参数k的取值,范围为[0,04,0.06]。

    代码测试一下:

    import cv2 
    import numpy as np
    
    img = cv2.imread('R-C.jpg')
    img_show=img.copy()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转灰度
    gray = np.float32(gray) # 转格式为float32
    dst = cv2.cornerHarris(gray, 2, 3, 0.04)
    img_show[dst>0.01*dst.max()]=[0,0,255] # dst.max()一定是一个角点,这里设置为所有dst矩阵中将
                                           # 大于最大值1%的值都标记成角点,以红色标记出来
    cv2.imshow('dst',img_show) 
    cv2.waitKey(0) 
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    角点检测结果如下:
    在这里插入图片描述
    本文详细介绍了角点检测的数学模型和代码实现,对数学模型不感兴趣的小伙伴可以直接查看代码实现,不动理论也不影响食用。下一节我们来介绍尺度空间,大家加油~

  • 相关阅读:
    npm not found: python2
    一次完整的渗透测试流程
    文件系统基础知识
    Vue Vuex模块化编码
    Javascript正则表达式常用的验证(验证手机号,电话,邮箱,网址等)
    AOP进阶-切入点表达式-@annotation
    NC15665 maze
    LeetCode算法题解(回溯,难点)|LeetCode37. 解数独
    火绒安全:全面守护你的数字世界
    前端笔试题总结,带答案和解析
  • 原文地址:https://blog.csdn.net/weixin_54929649/article/details/126563174