美文网首页
Haars角点检测

Haars角点检测

作者: 原上的小木屋 | 来源:发表于2020-06-07 21:33 被阅读0次

Hessian焦点检测

  1. 基本概念
  • 角点检测是检测边缘上的角点。
  • 角点是曲率变大的点,由高斯曲率来描述
  1. 高斯曲率公式
  • 高斯曲率公式K=\frac{det(H)}{(1+I^2_{x}+I^2_{y})^2}
  • 其中det(H)=I^{}_{xx}I^{}_{yy}−I^{2}_{xy}
  1. 高斯曲率公式解释
  • H 表示Hessian矩阵。图像的二次微分(通过将Sobel滤波器应用于灰度图像计算得来)。对于图像上的一点,按照下式定义:
  • I^{}_{x} :应用x方向上的Sobel滤波器;
  • I^{}_{y} :应用y方向上的Sobel滤波器;
  1. 公式理解
  • Hessian角点检测中,detH将极大点视为j角点。
  • 如果中心像素与其8−近邻像素相比值最大,则中心像素为极大点。
  • 解答中,角点是det(H)为极大值,并且大于max(det(H))⋅0.1的点。
  1. 代码分析
import cv2
import numpy as np
import matplotlib.pyplot as plt#导入图像处理的三个常用库
# Hessian corner detection hessian角点检测
def Hessian_corner(img):
    ## Grayscale
    def BGR2GRAY(img):#转灰度
        gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
        gray = gray.astype(np.uint8)
        return gray
    ## Sobel Sobel滤波
    def Sobel_filtering(gray):
        # get shape
        H, W = gray.shape
        # sobel kernel 构造不同方向上的sobel滤波器
        sobely = np.array(((1, 2, 1),
                           (0, 0, 0),
                           (-1, -2, -1)), dtype=np.float32)
        sobelx = np.array(((1, 0, -1),
                           (2, 0, -2),
                           (1, 0, -1)), dtype=np.float32)
        # padding 扩充图像边缘
        tmp = np.pad(gray, (1, 1), 'edge')
        # prepare 准备Ix Iy
        Ix = np.zeros_like(gray, dtype=np.float32)
        Iy = np.zeros_like(gray, dtype=np.float32)
        # get differential
        for y in range(H):
            for x in range(W):
                Ix[y, x] = np.mean(tmp[y: y + 3, x: x + 3] * sobelx)#生成Ix矩阵
                Iy[y, x] = np.mean(tmp[y: y + 3, x: x + 3] * sobely)#生成Iy矩阵
        Ix2 = Ix ** 2#得到Ix平方
        Iy2 = Iy ** 2#得到Iy平方
        Ixy = Ix * Iy#得到Ix与Iy的积
        return Ix2, Iy2, Ixy
    ## Hessian
    def corner_detect(gray, Ix2, Iy2, Ixy):
        # get shape
        H, W = gray.shape
        # prepare for show detection
        out = np.array((gray, gray, gray))
        out = np.transpose(out, (1, 2, 0))
        # get Hessian value
        Hes = np.zeros((H, W))
        for y in range(H):
            for x in range(W):
                Hes[y, x] = Ix2[y, x] * Iy2[y, x] - Ixy[y, x] ** 2#生成hassian矩阵
        ## Detect Corner and show
        for y in range(H):
            for x in range(W):
                if Hes[y, x] == np.max(Hes[max(y - 1, 0): min(y + 2, H), max(x - 1, 0): min(x + 2, W)]) and Hes[
                    y, x] > np.max(Hes) * 0.1:#选取角点
                    out[y, x] = [0, 0, 255]#将其标红
        out = out.astype(np.uint8)
        return out
    # 1. grayscale
    gray = BGR2GRAY(img)
    # 2. get difference image
    Ix2, Iy2, Ixy = Sobel_filtering(gray)
    # 3. corner detection
    out = corner_detect(gray, Ix2, Iy2, Ixy)
    return out
# Read image
img = cv2.imread("123.jpg").astype(np.float32)
# Hessian corner detection
out = Hessian_corner(img)
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)

Harris角点检测

基本思想

  • 算法基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。
    如何刻画
  • 当窗口发生[u,v]移动时,那么滑动前与滑动后对应的窗口中的像素点灰度变化描述如下
  • E(u,v)=\sum{w(x,y)[I(x+u,y+v)-I(x,y)]^2}
    公式解释
  • [u,v]是窗口的偏移量
  • (x,y)是窗口内所对应的像素坐标位置,窗口有多大,就有多少个位置
  • w(x,y)是窗口函数,最简单情形就是窗口内的所有像素所对应的w权重系数均为1。但有时候,我们会将w(x,y)函数设定为以窗口中心为原点的二元正态分布。如果窗口中心点是角点时,移动前与移动后,该点的灰度变化应该最为剧烈,所以该点权重系数可以设定大些,表示窗口移动时,该点在灰度变化贡献较大;而离窗口中心(角点)较远的点,这些点的灰度变化几近平缓,这些点的权重系数,可以设定小点,以示该点对灰度变化贡献较小,那么我们自然想到使用二元高斯函数来表示窗口函数
  • 根据上述表达式,当窗口处在平坦区域上滑动,可以想象的到,灰度不会发生变化,那么E(u,v) = 0;如果窗口处在比纹理比较丰富的区域上滑动,那么灰度变化会很大。算法最终思想就是计算灰度发生较大变化时所对应的位置,当然这个较大是指针任意方向上的滑动,并非单指某个方向。
    E(u,v)表达式进一步演化
  • f(x+u,y+v)\approx f(x,y)+uf^{}_{x}(x,y)++vf^{}_{y}(x,y)这个式子是一个很简单的二元泰勒公式一阶展开
  • 按照上述对E(u,v)=\sum{w(x,y)[I(x+u,y+v)-I(x,y)]^2}进行处理,即可得到E(u,v)\approx\sum{w(x,y)[uI^{}_{x}(x,y)+vI^{}_{y}(x,y)]^2}=\sum{w(x,y)[u^2I^{2}_{x}+v^2I^{2}_{y}+2uvI^{}_{x}I^{}_{y}]}
  • E(u,v)\approx\sum{w(x,y)} \left[ \begin{matrix} u &v \end{matrix} \right] \left[ \begin{matrix} I^{2}_{x} &I^{}_{x}I^{}_{y} \\ I^{}_{y}I^{}_{x}&I^{2}_{y} \end{matrix} \right] \left[ \begin{matrix} u \\v \end{matrix} \right] =\left[ \begin{matrix} u &v \end{matrix} \right](\sum{w(x,y)}\left[ \begin{matrix} I^{2}_{x} &I^{}_{x}I^{}_{y} \\ I^{}_{y}I^{}_{x}&I^{2}_{y} \end{matrix} \right])\left[ \begin{matrix} u &v \end{matrix} \right]
  • 这里我们取M=\sum{w(x,y)}\left[ \begin{matrix} I^{2}_{x} &I^{}_{x}I^{}_{y} \\ I^{}_{y}I^{}_{x}&I^{2}_{y} \end{matrix} \right]
  • 难道我们是直接求上述的E(u,v)值来判断角点吗?Harris角点检测并没有这样做,而是通过对窗口内的每个像素的x方向上的梯度与y方向上的梯度进行统计分析。这里以Ix和Iy为坐标轴,因此每个像素的梯度坐标可以表示成(Ix,Iy)。针对平坦区域,边缘区域以及角点区域三种情形进行分析.


    20170120232541519.jpg
  • 下图是对这三种情况窗口中的对应像素的梯度分布进行绘制:


    20170120232555296.png
  • 如果使用椭圆进行数据集表示,则绘制图示如下:
    20170120232729130.png
    20170120232734098.png
    因此可以得出下列结论:
  1. 特征值都比较大时,即窗口中含有角点
  2. 特征值一个较大,一个较小,窗口中含有边缘
  3. 特征值都比较小,窗口处在平坦区域
  • 于是R=detM-k(traceM)^2其中detM=\lambda^{}_{1}\lambda^{}_{2}traceM=\lambda^{}_{1}+\lambda^{}_{2}
  • 我们来看一下R=detM-k(traceM)^2的函数图像
    20170120232746954.png ,刚好满足上述特征,我们只需要对R给定阈值就可以得到角点位置坐标了,具体步骤如下
    基本步骤
  1. 对图像进行灰度化处理;
  2. 利用Sobel滤波器求出海森矩阵(Hessian matrix)
  3. 将高斯滤波器分别应用于I^{2}_{x}、I^{2}_{y}、I^{}_{x}I^{}_{y}
  4. 计算每个像素的R=det(H)−k (trace(H))^2。通常K在[0.04,0.16]范围内取值.
  5. 满足 R≥max(R)⋅th的像素点即为角点。
  6. 参数选取 高斯滤波器:k=3,σ=3;
    K=0.04,th=0.1
    代码分析
import cv2
import numpy as np
import matplotlib.pyplot as plt#导入三个常用的图像库
# Harris corner detection角点检测函数
def Harris_corner(img):
    ## Grayscale
    def BGR2GRAY(img):#图像转灰度
        gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
        gray = gray.astype(np.uint8)
        return gray
    ## Sobel
    def Sobel_filtering(gray):#两个方向上进行sobel滤波得到Ix核Iy
        # get shape
        H, W = gray.shape
        # sobel kernel
        sobely = np.array(((1, 2, 1),
                           (0, 0, 0),
                           (-1, -2, -1)), dtype=np.float32)
        sobelx = np.array(((1, 0, -1),
                           (2, 0, -2),
                           (1, 0, -1)), dtype=np.float32)
        # padding
        tmp = np.pad(gray, (1, 1), 'edge')
        # prepare
        Ix = np.zeros_like(gray, dtype=np.float32)
        Iy = np.zeros_like(gray, dtype=np.float32)
        # get differential
        for y in range(H):
            for x in range(W):
                Ix[y, x] = np.mean(tmp[y: y + 3, x: x + 3] * sobelx)
                Iy[y, x] = np.mean(tmp[y: y + 3, x: x + 3] * sobely)
        Ix2 = Ix ** 2
        Iy2 = Iy ** 2
        Ixy = Ix * Iy
        return Ix2, Iy2, Ixy
    # gaussian filtering
    def gaussian_filtering(I, K_size=3, sigma=3):#高斯滤波函数
        # get shape
        H, W = I.shape
        ## gaussian
        I_t = np.pad(I, (K_size // 2, K_size // 2), 'edge')
        # gaussian kernel高斯核的生成
        K = np.zeros((K_size, K_size), dtype=np.float)
        for x in range(K_size):
            for y in range(K_size):
                _x = x - K_size // 2
                _y = y - K_size // 2
                K[y, x] = np.exp(-(_x ** 2 + _y ** 2) / (2 * (sigma ** 2)))
        K /= (sigma * np.sqrt(2 * np.pi))
        K /= K.sum()#归一化高斯核
        # filtering
        for y in range(H):
            for x in range(W):
                I[y, x] = np.sum(I_t[y: y + K_size, x: x + K_size] * K)
        return I
    # corner detect
    def corner_detect(gray, Ix2, Iy2, Ixy, k=0.04, th=0.1):
        # prepare output image
        out = np.array((gray, gray, gray))
        out = np.transpose(out, (1, 2, 0))
        # get R 计算R
        R = (Ix2 * Iy2 - Ixy ** 2) - k * ((Ix2 + Iy2) ** 2)#Ix2、Iy2和Ixy均为海森矩阵中的元素
        # detect corner
        out[R >= np.max(R) * th] = [0, 0, 255]#将图像上色
        out = out.astype(np.uint8)
        return out
    # 1. grayscale#转灰度
    gray = BGR2GRAY(img)
    # 2. get difference image#sobel滤波之后得到的矩阵
    Ix2, Iy2, Ixy = Sobel_filtering(gray)
    # 3. gaussian filtering#对2得到的图像进行高斯滤波
    Ix2 = gaussian_filtering(Ix2, K_size=3, sigma=3)
    Iy2 = gaussian_filtering(Iy2, K_size=3, sigma=3)
    Ixy = gaussian_filtering(Ixy, K_size=3, sigma=3)
    # 4. corner detect角点检测
    out = corner_detect(gray, Ix2, Iy2, Ixy)
    return out
# Read image
img = cv2.imread("123.jpg").astype(np.float32)
# Harris corner detection
out = Harris_corner(img)
cv2.imwrite("out.jpg", out)
cv2.imshow("result", out)
cv2.waitKey(0)

相关文章

  • Haars角点检测

    Hessian焦点检测 基本概念 角点检测是检测边缘上的角点。 角点是曲率变大的点,由高斯曲率来描述 高斯曲率公式...

  • python 3+opencv 3.4(五)--图像特征提取

    应用:图像拼接、图像匹配 特征检测和提取算法:Harris(检测角点)SIFT(检测斑点blob)SURF(检测斑...

  • 计算机视觉 OpenCV Android | 特征检测与匹配之角

    本文要点总结(俩算法的联系与区别) Harris角点检测与Shi-Tomasi角点检测都是经典的角点特征提取算法,...

  • 第 8 章 检测兴趣点

    本章包括以下内容: 检测图像中的角点; 快速检测特征; 尺度不变特征的检测; 多尺度FAST 特征的检测。 8.2...

  • 核酸的琐事

    我们小区门外有两个核酸检测点,一个在东南角,一个在小区正东方向。 我偏爱东南角那个检测点,此处紧贴 13 号线地铁...

  • CV03_04:角点位置校正

      角点的位置校正也称亚像素角点检测算法,这个算法思想是基于经验与假设的。  (1)经验是:在角点所在的足够小的区...

  • 特征点检测算法

    特征点检测算法 Harris角点检测 SIFT特征检测 SURF特征检测 ORB特征检测

  • 图像特征提取:(一)Harri角点检测

    目录 一  Harri角点检测  1.1 何为角点检测?  1.2 Harri算子的数学表征  1.3 Openc...

  • 角点配对与图像匹配

    图像匹配能够应用的场合非常多,如目标跟踪,检测,识别,图像拼接等,而图像匹配最核心的技术就要属角点匹配了,所谓角点...

  • Harris角点检测算法

    角点检测算法

网友评论

      本文标题:Haars角点检测

      本文链接:https://www.haomeiwen.com/subject/mumctktx.html