精华内容
下载资源
问答
  • harris角点检测原理
    2020-06-22 21:46:51


    自己的理解,如有疏漏,敬请指正。

    Harris角点检测基本原理

    目的:寻找图像中像素值变化较大的点。

    基本概念

    1. 角点: 想象用一个滑动窗口在图像上面前后左右移动,在不均匀的区域,窗口中像素值都会发生很大变化。
    2. 角点和边缘的区别: 角点是无论窗口向哪个方向移动(左右/前后),像素值都会发生很大变化。而边缘是只有一个方向的像素值会发生变化。
      边缘与角点

    检测步骤

    角点检测基本思路:

    联想变化与梯度的关系
    梯度与差分的关系
    检测图片像素值变化
    检测图像梯度
    计算某邻域的灰度值求差分

    简单来说,就是用滑动窗口在图像上移动,计算窗口内的像素值变化,据此计算角点响应函数。如果某个窗口的响应函数值大于阈值,则认为这个窗口存在角点

    第一步:计算窗口内部的像素值变化量

    将图像窗口平移 [ u , v ] [u,v] [u,v] 产生的灰度值变化 E ( u , v ) = ∑ x , y w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] 2 E(u,v)=\sum_{x,y} w(x,y)[I(x+u,y+v)-I(x,y)]^2 E(u,v)=x,yw(x,y)[I(x+u,y+v)I(x,y)]2
    其中, ( x , y ) (x,y) (x,y)为窗口移动的起始中心位置, I ( x , y ) I(x,y) I(x,y)为这个位置的灰度值。窗口分别向 x x x y y y 方向移动 u u u v v v个像素, ( x + u , y + v ) (x+u,y+v) (x+u,y+v) 为新的中心点位置, I ( x + u , y + v ) I(x+u,y+v) I(x+u,y+v) 就是这个位置的灰度值。

    w ( x , y ) w(x,y) w(x,y)为位置 ( x , y ) (x,y) (x,y)处的窗口函数,表示窗口内各像素的权重。常见的窗口函数有均值、高斯等。

    公式的简化推导
    原理:二元函数泰勒展开
    f ( x + u , y + v ) ≈ f ( u , v ) + u f x ( x , y ) + v f y ( x , y ) f(x+u,y+v)\approx f(u,v)+uf_x(x,y)+vf_y(x,y) f(x+u,y+v)f(u,v)+ufx(x,y)+vfy(x,y)

    因此,对公式 E ( u , v ) = ∑ x , y w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] 2 E(u,v)=\sum_{x,y} w(x,y)[I(x+u,y+v)-I(x,y)]^2 E(u,v)=x,yw(x,y)[I(x+u,y+v)I(x,y)]2中的 [ I ( x + u , y + v ) − I ( x , y ) ] 2 [I(x+u,y+v)-I(x,y)]^2 [I(x+u,y+v)I(x,y)]2 可以化简:
    [ I ( x + u , y + v ) − I ( x , y ) ] 2 ≈ [ I ( x , y ) + u I x + v I y − I ( x , y ) ] 2 = [ u I x + v I y ] 2 = u 2 I x 2 + 2 u I x v I y + v 2 I y 2 [I(x+u,y+v)-I(x,y)]^2\\ \approx [I(x,y)+uI_x+vI_y-I(x,y)]^2\\ =[uI_x+vI_y]^2\\ =u^2I_x^2+2uI_xvI_y+v^2I_y^2 [I(x+u,y+v)I(x,y)]2[I(x,y)+uIx+vIyI(x,y)]2=[uIx+vIy]2=u2Ix2+2uIxvIy+v2Iy2
    其中 I x I_x Ix I y I_y Iy I I I的微分(偏导),在图像中就是求 x x x y y y 方向的梯度:
    I x = ∂ I ( x , y ) ∂ x I_x=\frac{\partial I(x,y)}{\partial x} Ix=xI(x,y) I y = ∂ I ( x , y ) ∂ y I_y=\frac{\partial I(x,y)}{\partial y} Iy=yI(x,y)
    代入 E ( u , v ) E(u,v) E(uv)可得:
    E ( u , v ) = ∑ x , y w ( x , y ) ( u 2 I x 2 + 2 u v I x I y + v 2 I y 2 ) = [ u v ] ∑ x , y w ( x , y ) [ I x 2 I x I y I x I y I y 2 ] [ u v ] = [ u v ] M [ u v ] E(u,v)=\sum_{x,y} w(x,y)(u^2I_x^2+2uvI_xI_y+v^2I_y^2)\\ =\begin{bmatrix} u&v \end{bmatrix}\quad \sum_{x,y} w(x,y)\begin{bmatrix} I_x^2& I_xI_y\\ I_xI_y& I_y^2 \end{bmatrix}\quad \begin{bmatrix} u\\v \end{bmatrix}\quad\\ =\begin{bmatrix} u&v \end{bmatrix}\quad M \begin{bmatrix} u\\v \end{bmatrix}\quad E(u,v)=x,yw(x,y)(u2Ix2+2uvIxIy+v2Iy2)=[uv]x,yw(x,y)[Ix2IxIyIxIyIy2][uv]=[uv]M[uv]
    其中, M = ∑ x , y w ( x , y ) [ I x 2 I x I y I x I y I y 2 ] M=\sum_{x,y} w(x,y)\begin{bmatrix} I_x^2& I_xI_y\\ I_xI_y& I_y^2 \end{bmatrix}\quad M=x,yw(x,y)[Ix2IxIyIxIyIy2]是实对称矩阵,可以进行对角化,表示为 M → Q − 1 [ λ 1 0 0 λ 2 ] Q M\to Q^{-1} \begin{bmatrix} \lambda_1&0\\ 0& \lambda_2\end{bmatrix}\quad Q MQ1[λ100λ2]Q
    λ 1 , λ 2 \lambda_1, \lambda_2 λ1,λ2是矩阵特征值,Q是特征向量组成的矩阵。可以把Q看成旋转因子,不影响两个正交方向的变化分量。

    第二步:计算角点响应函数

    每个窗口对应的角点响应函数 R = d e t ( M ) − k ( t r a c e ( M ) ) 2 R=det(M)-k(trace(M))^2 R=det(M)k(trace(M))2
    其中 d e t ( M ) = λ 1 λ 2 det(M)=\lambda_1\lambda_2 det(M)=λ1λ2 t r a c e ( M ) = λ 1 + λ 2 trace(M)=\lambda_1+\lambda_2 trace(M)=λ1+λ2 k k k是一个经验常数,在范围 (0.04, 0.06) 之间。

    (从第一步的分析 E ( u , v ) E(u,v) E(uv),到这里推导后,其实只要判断 M M M的特征值大小,就可以来寻找角点)

    第三步:判断角点

    算法的核心就是这个角点响应函数,构造得恰到好处,能够满足:
    角点的 ∣ R ∣ |R| R很大,平坦的区域 ∣ R ∣ |R| R很小,边缘的 ∣ R ∣ |R| R为负值

    1. 平坦区域: 窗口区域内的灰度值基本不会发生变化,像素点的梯度幅值非常小,即 I x I_x Ix I y I_y Iy都较小,此时矩阵M的两个特征值比较小,因此 ∣ R ∣ |R| R很小;
    2. 边缘区域: 边缘上的像素点在x或y某个方向的梯度幅值变化比较明显,另一个方向上的梯度幅值变化较小,M两个特征值一般是一个比较大,一个比较小(当然有特殊情况,比如45°的边缘,计算出的特征值并不是都特别的大,总之跟含有角点的分布情况还是不同的),因此 ∣ R ∣ |R| R一般为负值;
    3. 角点: 窗口区域内的灰度值变化非常大,M两个特征值都很大,因此 ∣ R ∣ |R| R很大。

    Harris角点检测程序

    python版(sobel算子)

    #角点检测
    import cv2 as cv
    from matplotlib import pyplot as plt
    import numpy as np
    
    image = cv.imread('Star.jpg')   #读取图像
    #  输出图像尺寸
    print(image.shape)
    height = image.shape[0]
    width = image.shape[1]
    channels = image.shape[2]
    print("width: %s  height: %s  channels: %s" % (width, height, channels))
    gray_img = cv.cvtColor(image, cv.COLOR_BGR2GRAY)  #cv2.COLOR_BGR2GRAYBGR格式转换成灰度图片
    # 将数据类型转化为float32
    gray_img = np.float32(gray_img)
    
    # 检测参数设置
    block_size = 3    #滑动窗口的尺寸
    sobel_size = 3    #用于计算梯度图的Sobel算子的尺寸
    k = 0.06          #参数k,取值范围在0.04~0.06之间
    
    # 输入灰度图(float32)及参数,计算角点响应函数
    corners_img = cv.cornerHarris(gray_img, block_size, sobel_size, k)
    
    # 放大结果来标注角点, not necessary
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
    '''这个函数的第一个参数表示内核的形状,有三种形状可以选择。
    矩形:MORPH_RECT;
    十字形:MORPH_CROSS;
    椭圆形:MORPH_ELLIPSE;
    第二和第三个参数分别是内核的尺寸以及锚点的位置。
    这里表示得到一个3*3的矩形
    '''
    dst = cv.dilate(corners_img, kernel)  #对圈圈进行膨胀操作
    
    # Threshold for an optimal value, marking the corners in Green
    # image[corners_img>0.01*corners_img.max()] = [0,0,255]
    
    for r in range(height):
        for c in range(width):
            pix = dst[r, c]
            if pix > 0.05 * dst.max():
                cv.circle(image, (c, r), 5, (0, 0, 255), 0)
    
    image1 = cv.cvtColor(image, cv.COLOR_BGR2RGB)
    
    plt.imshow(image1)
    plt.title("result")
    plt.show()
    

    结果

    matlab版

    % 功能:检测图像harris角点
    % in_image-待检测的rgb图像数组
    % a--角点参数响应,取值范围:0.04~0.06
    % [posr,posc]-角点坐标
    in_image=imread('Star.jpg');
    in_image=rgb2gray(in_image);
    I=double(in_image);
    %%%%计算xy方向梯度%%%%%
    fx=[-1,0,1];%x方向梯度模板
    Ix=filter2(fx,I);%x方向滤波
    fy=[-1;0;1];%y方向梯度模板(注意是分号)
    Iy=filter2(fy,I);
    %%%%计算两个方向梯度的乘积%%%%%
    Ix2=Ix.^2;
    Iy2=Iy.^2;
    Ixy=Ix.*Iy;
    %%%%使用高斯加权函数对梯度乘积进行加权%%%%
    %产生一个7*7的高斯窗函数,sigma值为2
    h=fspecial('gaussian',[7,7],2);
    IX2=filter2(h,Ix2);
    IY2=filter2(h,Iy2);
    IXY=filter2(h,Ixy);
    %%%%%计算每个像元的Harris响应值%%%%%
    [height,width]=size(I);
    R=zeros(height,width);
    %像素(i,j)处的响应值
    for i=1:height
        for j=1:width
            M=[IX2(i,j) IXY(i,j);IXY(i,j) IY2(i,j)];
            R(i,j)=det(M)-0.06*(trace(M))^2;
        end
    end
    %%%%%角点判断%%%%%
    Rmax=max(max(R));
    %阈值
    t=0.05*Rmax;
    for i=1:height
        for j=1:width
            if R(i,j)<t
                R(i,j)=0;
            end
        end
    end
    %%%%%进行3*3领域非极大值抑制%%%%%%%%%
    corner_peaks=imregionalmax(R);
    %imregionalmax对二维图片,采用8领域(默认,也可指定)查找极值,三维图片采用26领域
    %极值置为1,其余置为0
    num=sum(sum(corner_peaks));
    %%%%%%显示所提取的Harris角点%%%%
    [posr,posc]=find(corner_peaks==1);
    figure;
    imshow(in_image);
    hold on
    for i=1:length(posr)
        plot(posc(i),posr(i),'ro');
    end
    

    结果:
    在这里插入图片描述

    边缘区域存在误差
    这是由于进行角点判断时阈值偏高。将程序中t=0.06*Rmax改成t=0.02*Rmax,则效果变好:
    在这里插入图片描述

    资料

    Datawhale计算机视觉基础:图像处理(下)

    更多相关内容
  • Harris角点检测原理与流程
  • harris角点检测原理

    千次阅读 2021-07-23 22:23:36
    基于图像灰度的方法通过计算的曲率及梯度来检测角点。 2、数学知识 1)泰勒展开 泰勒展开公式是一种统一的形式,非常完美。 一维泰勒展开公式: 二维泰勒展开公式: 2)矩阵的特征值和特征向量 ...

    目录

    1、角点概述

    2、数学知识

    3、Harris角点检测基本原理

    4、优化改进


    1、角点概述

            如果一个点在任意方向的一个微小变动都会引起灰度很大的变化,那么我们就把它称之为角点,也就是一阶导数(即灰度图的梯度)中的局部最大所对应的像素点就是角点。在现实世界中,角点对应于物体的拐角,道路的十字路口、丁字路口等。基于图像灰度的方法通过计算点的曲率及梯度来检测角点。

    2、数学知识

    1)泰勒展开

            泰勒展开公式是一种统一的形式,非常完美。

            一维泰勒展开公式:

            二维泰勒展开公式:

    2)矩阵的特征值和特征向量

     harris边角(兴趣点)检测算法 - 知乎

    3、Harris角点检测基本原理

            人眼对角点的识别通常是在一个局部的小区域或小窗口完成的。如果在各个方向上移动这个特征的小窗口,窗口内区域的灰度发生了较大的变化,那么就认为在窗口内遇到了角点。如果这个特定的窗口在图像各个方向上移动时,窗口内图像的灰度没有发生变化,那么窗口内就不存在角点;如果窗口在某一个方向移动时,窗口内图像的灰度发生了较大的变化,而在另一些方向上没有发生变化,那么,窗口内的图像可能就是一条直线的线段。

            Harris 检测器具有旋转不变性,但不具有尺度不变性,也就是说尺度变化可能会导致角点变为边缘,如下图所示:

            想要尺度不变特性的话,可以关注SIFT特征。

    Harris 角点检测算法分为以下三步:

            1、当窗口同时向 x 和 y 两个方向移动时,计算窗口内部的像素值变化量E(u,v);

            2、对于每个窗口,都计算其对应的一个角点响应函数R;

            3、然后对该函数进行阈值处理,如果R > threshold,表示该窗口对应一个角点特征。

    E(u,v)推导过程:

            首先,将图像窗口平移[u,v]产生灰度变化的自相关函数如下:

            其中窗口函数(权重矩阵)可以是平坦的,也可以是高斯的,是一个二维的滤波器。对于一个角点来说, E(u,v)会非常大。因此,我们可以最大化上面这个函数来得到图像中的角点。用上面的函数计算会非常慢。因此,我们使用泰勒展开式(只有一阶)来得到这个公式的近似形式。

            将平移后的式子进行泰勒展开如下:

             其中Ix和Iy是I的偏微分,在图像中就是在x和y方向的梯度图(可以通过cv2.Sobel()来得到):

            接下来继续推导:

             把u和v拿出来,得到最终的形式:

            其中矩阵M为:

             最后是把实对称矩阵对角化处理后的结果,可以把R看成旋转因子,其不影响两个正交方向的变化分量。经对角化处理后,将两个正交方向的变化分量提取出来,就是 λ1 和 λ2(特征值)。

            对于图像的每一个像素点(x,y),对应一个以该像素为中心的窗口w(x,y),然后该像素平移(u,v)得到新的像素点(x+u,y+v),而E(u,v)就是窗口中所有像素的加权和乘以不同位置像素的灰度差值。

            矩阵M又称为Harris矩阵。w(x,y)的宽度决定了在像素x 周围的感兴趣区域。

    计算响应函数R:

            得到E(u,v)的最终形式,我们的目的是要找到会引起较大的灰度值变化的那些窗口。灰度值变化的大小则取决于矩阵M,那么如何找到这些窗口,我们可以使用矩阵的特征值来实现。

            忽略余项之后的表达式为一个二项式函数,然而二项式函数的本质上就是一个椭圆函数,椭圆的扁率和尺寸是由M(x,y)的特征值λ1、λ2决定的,椭圆的方向是由M(x,y)的特征矢量决定的,如下图所示,椭圆方程为:

             椭圆函数特征值与图像中的角点、直线(边缘)和平面之间的关系如下图所示。共可分为三种情况:

            a)图像中的直线。一个特征值大,另一个特征值小,λ1>λ2或λ2>λ1。自相关函数值在某一方向上大,在其他方向上小。

            b)图像中的平面。两个特征值都小,且近似相等;自相关函数数值在各个方向上都小。

            c)图像中的角点。两个特征值都大,且近似相等,自相关函数在所有方向都增大。

            通过M的两个特征值λ1和λ2的大小对图像点进行分类:

             如果λ1和λ2都很小,图像窗口在所有方向上移动都无明显灰度变化。由于我们是通过M的两个特征值的大小对图像进行分类,所以,定义角点相应函数R:

              其中k为经验常数,一般取k=0.04~0.06。为了去除加权常数κ,我们通常使用商数detM/(traceM)2作为指示器。所以,上图可以转化为:

             因为特征值λ1和λ2决定了R的值,R 只与M的特征值有关,所以我们可以用特征值来决定一个窗口是平面、边缘还是角点。

            平面:该窗口在平坦区域上滑动,窗口内的灰度值基本不会发生变化,所以|R|值非常小,在水平和竖直方向的变化量均较小,即Ix和Iy都较小,那么λ1和λ2都较小;

            边缘:R值为负数,仅在水平或竖直方向有较大的变化量,即Ix和Iy只有一个较大,也就是λ1>>λ2或λ2>>λ1;

            角点:R值很大,在水平、竖直两个方向上变化均较大的点,即Ix和Iy都较大,也就是λ1和λ2都很大。

    最优角点判别:

            根据R的值,将这个窗口所在的区域划分为平面、边缘或角点。为了得到最优的角点,我们还可以使用非极大值抑制。        

            Harris角点检测的结果是带有这些分数R的灰度图像,设定一个阈值,R > threshold,分数大于这个阈值的像素就对应角点。

    4、优化改进

    1)由于Harris角点检测算法的稳定性和k值有关,而k是个经验值,不好设定最佳值。

            Shi-Tomasi发现,角点的稳定性其实和矩阵M的较小特征值有关,于是直接用较小的那个特征值作为分数。这样就不用调整k值了。

            所以Shi-Tomasi将分数公式改为如下形式:

            和Harris一样,如果该分数大于设定的阈值,我们就认为它是一个角点。

    2)Harris和Shi-Tomasi都是基于梯度计算的角点检测方法,Shi-Tomasi的效果要好一些。基于梯度的检测方法有一些缺点: 计算复杂度高,图像中的噪声可以阻碍梯度计算。

            想要提高检测速度的话,可以考虑基于模板的方法:FAST角点检测算法。该算法原理比较简单,但实时性很强。

    3)Harris 检测器具有旋转不变性,但不具有尺度不变性,也就是说尺度变化可能会导致角点变为边缘,如下图所示:

            想要尺度不变特性的话,可以关注SIFT特征。

    相关链接:

    1、harris角点检测算法实现

    2、SHI-TOMASI角点检测

    展开全文
  • Harris角点检测原理

    2019-04-18 11:55:31
    Harris角点检测是基于Moravec角点检测之上的, Moravec角点检测算子的思想其实特别简单,在图像上取一个W*W的“滑动窗口”,不断的移动这个窗口并检测窗口中的像素变化情况E。像素变化情况E可简单分为以下三种:A ...

    Harris角点检测是基于Moravec角点检测之上的, Moravec角点检测算子的思想其实特别简单,在图像上取一个W*W的“滑动窗口”,不断的移动这个窗口并检测窗口中的像素变化情况E。像素变化情况E可简单分为以下三种:A 如果在窗口中的图像是什么平坦的,那么E的变化不大。B 如果在窗口中的图像是一条边,那么在沿这条边滑动时E变化不大,而在沿垂直于这条边的方向滑动窗口时,E的变化会很大。 C 如果在窗口中的图像是一个角点时,窗口沿任何方向移动E的值都会发生很大变化。
    在这里插入图片描述
    用数学表达式就是:
    在这里插入图片描述
    (u,v)就表示四个移动方向(1,0)(1,1)(0,1)(-1,1),其中w为窗函数(window function),I为图像梯度,那么E就表示了灰度变化的剧烈程度

    1977年,Moravec最先提出了如下的角点检测方法:

    1. 对于原始图像,取偏移量(Δx,Δy)为(1,0),(1,1),(0,1),(-1,1),分别计算每一像素点(xi,yi)的灰度变化
    2. 对于每一像素点(xi,yi),计算角点响应函数R(xi,yi)=min E
    3. 设定阈值T,将角点响应函数R(xi,yi)中低于T的值设为0
    4. 在窗口范围内进行非极大值抑制:遍历角点响应函数,若某个像素的角点响应函数在窗口内不是最大,该像素置0
    5. 选择非零点作为角点检测结果

    Moravec角点检测的缺点

    1. 二值的窗口函数导致角点响应函数不够光滑
    2. 只在四个方向上计算灰度值变化,导致角点响应函数在多处都有较大响应
    3. 对于每个点只考虑E的最小值,导致算法对边缘有很强的反应

    1988年,Harris和Plessey对Moravec的方法进行了改进,提出了经典的Harris角点检测算法。Harris首先将Moravec算法中的窗口函数由阶跃函数改为二维高斯函数,并通过泰勒展开考察微小移动,也就是说,如果要求E的最大值以明确角点,就可以令 u , v → 0 u,v \rightarrow 0 u,v0,对E做泰勒展开,得

    E ( u , v ) = ( u , v ) M ( u v ) E(u, v)=(u, v) M \left( \begin{array}{l}{u} \\ {v}\end{array}\right) E(u,v)=(u,v)M(uv)
    M = ∑ ( x , y ) w ( x , y ) ( I X 2 I X I Y I X I Y I Y 2 ) = ( ∑ W I X 2 ∑ W I X I Y ∑ W I X I Y ∑ W I Y 2 ) M=\sum_{(x, y)} w(x, y) \left( \begin{array}{cc}{I_{X}^{2}} & {I_{X} I_{Y}} \\ {I_{X} I_{Y}} & {I_{Y}^{2}}\end{array}\right)=\left( \begin{array}{cc}{\sum_{W} I_{X}^{2}} & {\sum_{W} I_{X} I_{Y}} \\ {\sum_{W} I_{X} I_{Y}} & {\sum_{W} I_{Y}^{2}}\end{array}\right) M=(x,y)w(x,y)(IX2IXIYIXIYIY2)=(WIX2WIXIYWIXIYWIY2)

    M = ( A B B C ) M=\left( \begin{array}{ll}{A} & {B} \\ {B} & {C}\end{array}\right) M=(ABBC),则上式可以写成 A u 2 + 2 B u v + C v 2 = E A u^{2}+2 B u v+C v^{2}=E Au2+2Buv+Cv2=E 的形式,这表示了一个椭圆,自相关矩阵M描述了图像局部区域的灰度变化趋势,可以通过椭圆的形状来判定角点。
    下面解释下上面的内容:
    1.窗口函数的两种形式:
    窗口函数的两种形式
    2.泰勒公式展开:
    ,任何一个函数表达式,均可有泰勒公式进行展开,以逼近原函数,我们可以对下面函数进行一阶展开:
    f ( x + u , y + v ) ≈ f ( x , y ) + u f x ( x , y ) + v f y ( x , y ) f(x+u, y+v) \approx f(x, y)+u f_{x}(x, y)+v f_{y}(x, y) f(x+u,y+v)f(x,y)+ufx(x,y)+vfy(x,y)
    那么:
    ∑ [ I ( x + u , y + v ) − I ( x , y ) ] 2 \sum[I(x+u, y+v)-I(x, y)]^{2} [I(x+u,y+v)I(x,y)]2
    ≈ ∑ [ I ( x , y ) + u I x + v I y − I ( x , y ) ] 2 \approx \sum\left[I(x, y)+u I_{x}+v I_{y}-I(x, y)\right]^{2} [I(x,y)+uIx+vIyI(x,y)]2
    = ∑ u 2 I x 2 + 2 u v I x I y + v 2 I y 2 =\sum u^{2} I_{x}^{2}+2 u v I_{x} I_{y}+v^{2} I_{y}^{2} =u2Ix2+2uvIxIy+v2Iy2
    = ∑ [ u v ] [ I x 2 I x I y I x I y I y 2 ] [ u v ] =\sum \left[ \begin{array}{cc}{u} & {v}\end{array}\right] \left[ \begin{array}{cc}{I_{x}^{2}} & {I_{x} I_{y}} \\ {I_{x} I_{y}} & {I_{y}^{2}}\end{array}\right] \left[ \begin{array}{l}{u} \\ {v}\end{array}\right] =[uv][Ix2IxIyIxIyIy2][uv]
    = [ u v ] ( ∑ [ I x 2 I x I y I x I y I y 2 ] ) [ u v ] =\left[ \begin{array}{ll}{u} & {v}\end{array}\right]\left(\sum \left[ \begin{array}{cc}{I_{x}^{2}} & {I_{x} I_{y}} \\ {I_{x} I_{y}} & {I_{y}^{2}}\end{array}\right]\right) \left[ \begin{array}{l}{u} \\ {v}\end{array}\right] =[uv]([Ix2IxIyIxIyIy2])[uv]

    把中间看成矩阵M,则:
    E ( u , v ) ≅ [ u , v ] M [ u v ] E(u, v) \cong[u, v] M \left[ \begin{array}{l}{u} \\ {v}\end{array}\right] E(u,v)[u,v]M[uv]

    M = [ ∑ I x 2 ∑ I x I y ∑ I x I y ∑ I y 2 ] = [ λ 1 0 0 λ 2 ] M=\left[ \begin{array}{cc}{\sum I_{x}^{2}} & {\sum I_{x} I_{y}} \\ {\sum I_{x} I_{y}} & {\sum I_{y}^{2}}\end{array}\right]=\left[ \begin{array}{cc}{\lambda_{1}} & {0} \\ {0} & {\lambda_{2}}\end{array}\right] M=[Ix2IxIyIxIyIy2]=[λ100λ2]

    现在回到椭圆函数那里,至于椭圆函数的得来,查到的是通过微分思想化简而来,具体的还没深究,
    对于椭圆 A x 2 + 2 B x y + C y 2 = 1 A x^{2}+2 B x y+C y^{2}=1 Ax2+2Bxy+Cy2=1 ,设其半长轴和半短轴分别为a,b,那么 1 a , 1 b \frac{1}{\sqrt{a}}, \frac{1}{\sqrt{b}} a 1,b 1 是矩阵M的特征值。(特征值的含义见添加链接描述)

    在这里插入图片描述
    将上面的点用一个椭圆轮廓包围
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    得到M的特征值有什么用呢?若用奇异值分解的观点看这个问题。由于Jacobian矩阵 J = ( I X I Y ) J=\left( \begin{array}{l}{I_{X}} \\ {I_{Y}}\end{array}\right) J=(IXIY),故M=JJ^T,这样M的特征值开根号后就是J的奇异值,因此M的特征值就可以体现IX和IY的相对大小。

    现在我们需要定义角点响应函数,进一步进行区分,令(一般k=0.04 ~ 0.06)
    R = det ⁡ ( M ) − k tr ⁡ 2 ( M ) R=\operatorname{det}(M)-k \operatorname{tr}^{2}(M) R=det(M)ktr2(M)
    M = [ ∑ I x 2 ∑ I x I y ∑ I x I y ∑ I y 2 ] = [ λ 1 0 0 λ 2 ] M=\left[ \begin{array}{cc}{\sum I_{x}^{2}} & {\sum I_{x} I_{y}} \\ {\sum I_{x} I_{y}} & {\sum I_{y}^{2}}\end{array}\right]=\left[ \begin{array}{cc}{\lambda_{1}} & {0} \\ {0} & {\lambda_{2}}\end{array}\right] M=[Ix2IxIyIxIyIy2]=[λ100λ2]
    其中:
    det ⁡ ( M ) = λ 1 λ 2 = ∑ W I X 2 ⋅ ∑ W I Y 2 − ( ∑ W I X I Y ) 2 \operatorname{det}(M)=\lambda_{1} \lambda_{2}=\sum_{W} I_{X}^{2} \cdot \sum_{W} I_{Y}^{2}-\left(\sum_{W} I_{X} I_{Y}\right)^{2} det(M)=λ1λ2=WIX2WIY2(WIXIY)2
    tr ⁡ ( M ) = λ 1 + λ 2 = ∑ W I X 2 + ∑ W I Y 2 \operatorname{tr}(M)=\lambda_{1}+\lambda_{2}=\sum_{W} I_{X}^{2}+\sum_{W}I_{Y}^{2} tr(M)=λ1+λ2=WIX2+WIY2

    在这里插入图片描述

    在这里插入图片描述
    一般增大k的值,将减小角点响应值R,降低角点检测的灵性,减少被检测角点的数量;减小k值,将增大角点响应值R,增加角点检测的灵敏性,增加被检测角点的数量。

    参考博客:
    https://www.jianshu.com/p/6ae09c3d226f
    https://blog.csdn.net/newthinker_wei/article/details/45603583
    https://zhuanlan.zhihu.com/p/42490675
    https://zhuanlan.zhihu.com/p/36382429
    https://blog.csdn.net/fengye2two/article/details/79119736

    展开全文
  • Harris 角点检测原理及实现

    千次阅读 2020-07-17 21:02:51
    Harris中也是根据角点定义经角点定义,Harris中使用该像素周围像素块和其周围的其它像素块的相关性刻画角点,相关性用平方差之和进行计算(SSD),SSD越大,相关性差,中心像素越有可能成为角点。其数学表达形式为...

    1. 图像中角点定义

    沿各个方向,图像灰度均发生变化;

    2.Harris原理

    Harris中也是根据角点定义经角点定义,Harris中使用该像素点周围像素块和其周围的其它像素块的相关性刻画角点,相关性用平方差之和进行计算(SSD),SSD越大,相关性差,中心像素点越有可能成为角点。其数学表达形式为:
    在这里插入图片描述在这里插入图片描述
    Where Q 是矩阵M的特征向量组成的正交矩阵,向量左乘正交矩阵相当于旋转了一定角度,但是大小保持不变。
    在x轴和y轴梯度均增大的点就是梯度点,为了方便,设置相应函数,相应函数的设计原理如下图所示:
    在这里插入图片描述
    图(1) Harris角点检测原理图
    响应函数为:
    在这里插入图片描述
    Where K是一个经验值,通常取0.04~0.06。

    3.Harris代码实现

    '''
    @Author:noodles
    @date:2020-7-17 20:31:46
    '''
    import cv2
    import numpy as np
    threshold = 0.01
    def responseFunc(M):
        k = 0.04
        det = np.linalg.det(M)
        trace = np.trace(M)
        R = det - k * trace **2
        return R
    def getHarrisFeaturePoints(src,NMS=False):
        global threshold
        h, w = src.shape[:2]
        # Step1: convert rgb image grayScale
        gray_image = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
        cornerPoint = np.zeros_like(gray_image,dtype=np.float32)
        # Step2: compute gradient of x,y axis respectively
        grad = np.zeros((h, w, 2), dtype=np.float32)
        grad[:,:,0] = cv2.Sobel(gray_image,cv2.CV_16S,1,0)
        grad[:,:,1] = cv2.Sobel(gray_image,cv2.CV_16S,0,1)
    
        Ixx = grad[:,:,0] ** 2
        Iyy = grad[:,:,1] ** 2
        Ixy = grad[:,:,0] * grad[:,:,1]
        # gaussian_kernal =cv2.getGaussianKernel(3,2)
        Ixx = cv2.GaussianBlur(Ixx, (3, 3), sigmaX=2)
        Iyy = cv2.GaussianBlur(Iyy, (3, 3), sigmaX=2)
        Ixy = cv2.GaussianBlur(Ixy, (3, 3), sigmaX=2)
        # print(Ixx, Iyy,Ixy)
        # Step3: compute structure matrix
        for i in range(gray_image.shape[0]):
            for j in range(gray_image.shape[1]):
                struture_matrix = [[Ixx[i][j], Ixy[i][j]], [Ixy[i][j], Iyy[i][j]]]
    
                # Step4: response calculation,determine weather it is corner or not
                R = responseFunc(struture_matrix)
                cornerPoint[i][j] = R
    
        # Step5: non-max suppression,reduce the quantity of corner
        corners = np.zeros_like(gray_image,dtype=np.float32)
        counter = 0
        maxValue = np.max(cornerPoint)
        for i in range(cornerPoint.shape[0]):
            for j in range(cornerPoint.shape[1]):
                if NMS:
                    if cornerPoint[i][j] > threshold * maxValue and cornerPoint[i][j] == np.max(cornerPoint[max(0, i - 1):min(i + 1, h - 1), max(0, j - 1):min(j + 1, w - 1)] ):
                        counter+=1
                        corners[i][j] = 255
                else:
                    if cornerPoint[i][j] > threshold * maxValue:
                        counter+=1
                        corners[i][j] = 255
                        
        print('FeaturePoints=', counter)
        return corners
    
    
    
    if __name__ == '__main__':
    
        image_path = 'grid.jpg'
    
        src = cv2.imread(image_path)
        img = cv2.resize(src, dsize=(600, 400))
        NMS = False
        dst = getHarrisFeaturePoints(img,NMS)
        #print(dst)
        img[dst == 255] = [0, 0, 255]
        cv2.imshow('src',img)
        cv2.waitKey()
    
    
    
    

    实验结果:

    在这里插入图片描述
    图(2) opencv库函数测试结果
    在这里插入图片描述

    图(3) 编码实现测试结果
    可以看到对于同一张图,调用opencv和和自己编码实现检测的角点的位置和数量一致,验证了自己代码的正确性。

    4.疑难和理解

    Q1:为什么研究M矩阵?

    A1:根据化简式子1,发现M影响E(x,y)变化快慢。

    Q2:为什么要求M的特征值?

    在这里插入图片描述
    图(4) 矩阵特征值和Ix,Iy分布关系图
    理解思路1:绘制了特征值和窗口内Ix,Iy的函数,如上图(4),发现了对应结论。
    理解思路2:发现M矩阵和PCA中的矩阵很相似,原始数据可以理解为窗口中的Ix,Iy二维数据,M的特征值对应Ix,Iy的主成分,两个主成分都比较大,则认为在像素点周围存在至少两个像素变化的方向。

    Q3:响应函数设计的原理?

    A3:为了避免计算特征值。
    在这里插入图片描述
    图(5)原文中响应函数设计原理
    在这里插入图片描述
    图(6)Harris响应函数的曲线图
    结合Harris函数的本身特点和二维矩阵与特征值与矩阵元素的关系设计。
    矩阵值和矩阵元素存在如下关系:
    在这里插入图片描述

    Q4:为什么具有旋转不变性?

    A4:图像旋转只会改变特征椭圆的方向,并不会改变椭圆的长短轴的长度,因此R并不会改变。

    Q5:Harris角点检测算子对亮度和对比度的变化不灵敏

    在这里插入图片描述
    该算法通过图像差分计算角点,两种对比度变化如上图所示,可见光照图像差分影响并不大,也不会改变角点在图像中的位置,但是因为阈值设置的原因,会形象特征点的数量。
    Note:
    交单检测主要分为基于灰度图像的角点检测、基于二值图像的角点检测、基于轮廓曲线的角点检测。而Harris角点检测属于基于灰度图像的角点检测。
    下面这张图像使用基于灰度检测的角点图像效果就会很差:
    在这里插入图片描述
    原图
    在这里插入图片描述
    使用Harris角点检测出来的结果
    通过对比发现,角点检测过程,首先需要确定角点的种类,然后选用不同的角点检测算法,这样才能有效准确的检测处图像角点。

    5.reference

    参考文献:
    [1]: https://www.cnblogs.com/zyly/p/9508131.html
    [2]: https://www.cnblogs.com/ronny/p/4009425.html
    [3]: https://blog.csdn.net/f290131665/article/details/80064479
    [4]: A Combined Corner and Edge Detector[J],1988.Jianbo Shi and Carlo Tomasi

    展开全文
  • 为便于理解,先简要介绍角点的概念和角点检测背景一、角点角点检测背景:角点概念:角点,通常可理解为两条边的角点,也可理解为像素值在多个方向有显著变化的或局部区域内某个属性明显的。如多个轮廓的交界处...
  • harris角点检测原理和实现步骤说明

    热门讨论 2009-12-26 17:51:34
    提供了一个关于harris焦点检测原理详细教程链接网址,给出了实现harris角点检测的步骤和VC代码,希望对研究角检测的人有帮助,找了很久才收集到得。
  • 网上也有很多博客对Harris角点检测原理进行描述,但基本上只是描述了算法流程,而其中相关细节并未作出解释,这里我想对有些地方做出补充说明,正所谓知其然知其所以然,如有不对,还望指正。1. 何为角?下面有...
  • Harris角点检测原理详解

    万次阅读 多人点赞 2017-01-20 23:34:03
    网上也有很多博客对Harris角点检测原理进行描述,但基本上只是描述了算法流程,而其中有关细节并未作出解释,这里我想对有些地方做出解释,如有不对,还请指正。 1. 首先,何为角? 下面有两副不同视角的图像,...
  • 详细介绍(图文): Harris角点检测基本思想 数学表达 小结
  • Harris角点检测原理详解
  • 计算机视觉–Harris角点检测实现与分析(二)一、Harris角点检测1.1 基本原理1.2 数学表达二、代码实现三、结果与分析3.1 不同场景的R值讨论3.2 参数k对角点检测的影响四、总结 关于Harris角点检测的基本概念和不同...
  • 1. 何为角点 2. 角点检测算法基本思想是什么 3.如何用数学方法去刻画角点特征 4.E(u,v)表达式进一步演化 5.矩阵M的关键性 6. 如何度量角点响应
  • python+OpenCV笔记(二十二):角点检测原理Harris角点检测原理、Shi-Tomasi角点检测原理
  • 文章目录概念一、角点检测原理二、opencv 函数支持 cornerHarris() 概念 特征提取 特征提取是计算机视觉和图像处理中的一个概念。特征指的是唯一可识别的特性。特征提取是使用计算机提取图像信息,决定每个图像的...
  • import cv2 as cv import numpy as np """"" cv2.cornerHarris() 可以用来进行角点检测。...Harris角点检测的结果是灰度图,图中的值为角点检测的打分值。需要选取合适的阈值对结果进行二值化来检测
  • Harris 角点检测原理详解

    千次阅读 2017-05-15 20:40:32
    这篇文章主要介绍的Harris角点检测的算法原理,比较著名的角点检测方法还有jianbo Shi和Carlo Tomasi提出的Shi-Tomasi算法,这个算法开始主要是为了解决跟踪问题,用来衡量两幅图像的相似度,我们也可以把它看为...
  • OpenCV——Harris角点检测

    千次阅读 2021-10-10 08:30:35
    OpenCV——harris角点检测算法的C++与python代码实现。
  • 这篇文章整理两个图像处理中非常重要的算法,一个是Harris角点检测算法,另一个是SIFT特征匹配算法,这两个算法本质上还是去找图像里面的关键特征,帮助我们后续更好的理解图像以及做各种各样的分析。 由于这两个...
  • #include "my_harris.h"#define pi 3.14my_Harris::my_Harris(){}void my_Harris::RGB2GRAY(Mat rgb_img, Mat &gray_img){Mat img_src=rgb_img.clone();int rows =img_src.rows;int cols =img_src.cols;Mat img_...
  • 在学习时主要参考了1.http://blog.csdn.net/xiaowei_cqu/article/details/7805206和opencv-python官方的关于harris的文档...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,611
精华内容 1,044
关键字:

harris角点检测原理