Harris 角点学习笔记

Harris 角点学习笔记

本博客内容来源于网络以及其他书籍,结合自己学习的心得进行重编辑,因为看了很多文章不便一一标注引用,如图片文字等侵权,请告知删除。

角点的定义

角点通常被定义为两条边的交点,更严格的说,角点的局部邻域应该具有两个不同区域的不同方向的边界。或者说,角点就是多条轮廓线之间的交点。如下图中红色圈中标出的位置:


直观上或者从字面意思上很容易看出角点是什么,在哪里,那么从数字图像处理的角度来看的话,可以描述如下: - 像素点附近区域像素无论是在梯度方向、还是在梯度幅值上都发生较大的变化。 - 一阶导数(即灰度的梯度)的局部最大所对应的像素点; - 两条及两条以上边缘的交点; - 图像中梯度值和梯度方向的变化速率都很高的点; - 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。 可能暂时对于个别描述还没有太理解,我们在下面Harris 角点检测思路中,再理解。

为什么要检测角点

首先角点是图像中很重要的特征,对图像图形的理解和分析有很重要的作用。角点在保留图像图形重要特征的同时,可以有效地减少信息的数据量,使其信息的含量很高,有效地提高了计算的速度,有利于图像的可靠匹配,使得实时处理成为可能。对于同一场景,即使视角发生变化,角点通常具备稳定性质的特征。 角点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,由于角点检测的实时性以及稳定性,广泛应用于运动检测、图像匹配、视频跟踪、三维建模和目标识别等领域中。角点作为一种特征点,角点检测也称为特征点检测。 在实际的视觉用用中,大多数的角点检测方法检测的是拥有特定特征的图像点,而不仅仅是“角点”。这些特征点在图像中有具体的坐标,并具有某些数学特征,如局部最大或最小灰度、某些梯度特征等。 常见的传统角点检测算法有以下几种: - Moravec 角点检测算法 - Harris 角点检测算法 - Shi-Tomasi 角点检测算法 - FAST角点检测算法 - Forstner 角点检测算法 本文主要来解释Harris 角点检测算法,在之后的文章中会对其他算法进行详解。

角点检测的困难点

现有的角点检测算法并不是都十分的鲁棒。很多方法都要求有大量的训练集和冗余数据来防止或减少错误特征的出现。角点检测方法的一个很重要的评价标准是其对多幅图像中相同或相似特征的检测能力,对不同质量不同分辨率的图像都能有着比较好的角点检测能力,并且能够应对光照变化、图像旋转等图像变化。 角点作为比较基础的特征点,其检测速度也是一个重要的指标。


看看娜美桑放松一下


Harris 角点检测思路

角点检测算法基本思想是使用一个固定窗口(取某个像素的一个邻域窗口)在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。如下图


- 在左图中,当窗口在平坦的地方移动窗口,图像灰度值不会有太多变化。 - 在中间图中,如果我们在边缘移动窗口,沿着边缘方向移动,灰度值变化不大;沿着垂直于边缘方向移动,窗口内灰度值变化很大。(那是不是边缘可以这样检测呢) - 在右图中,如果我们在角落移动窗口,在任何方向移动灰度值变化都很大。 直观上,很容易理解那么在数字图像上该怎么来实现这个过程呢?

首先我们用数学的方法描述一下窗口在图片上滑动时像素点灰度变化描述


我们来解释一下公式中每部分的含义 - [u,v]是窗口的偏移量 - (x,y)是窗口内所对应的像素坐标位置,窗口有多大,就有多少个位置 - w(x,y)是窗口函数 - I(x,y) 是平移前窗口某点的像素值,I(x+u,y_v)时窗口平移后对应点的像素值

我们在看懂这个这个公式的基础上,继续接下来的推导,我们通过对灰度变化部分(即有uv参加的部分)进行泰勒展开得到


其中第一个约等于是对I(x+u,y+v)的一阶近似,其中Ix和Iy分别是像素在x,y方向上的梯度。下一个等号是对一阶近似后的式子化简再做平方展开得到的,改写成矩阵的形式侧可以得到最后的结果

所以我们可以将E(u,v)进行整理得



我们可以看出灰度变化的大小主要取决于中间的括号,我们把中间的括号单独表示



如果我们直接来进行计算,计算量将是比较大的,而且不好度量,所以harris是这样做的,通过对窗口内的每个像素的x方向上的梯度与y方向上的梯度进行统计分析。这里以Ix和Iy为坐标轴,因此每个像素的梯度坐标可以表示成(Ix,Iy)。针对平坦区域,边缘区域以及角点区域三种情形进行分析,统计分析图如下:



使用椭圆进行数据集表示如下



  • 在平坦区域上的每个像素点所对应的(IX,IY)坐标分布在原点附近,平坦区域的像素点梯度方向虽然各异,但是其幅值都不是很大,所以均聚集在原点附近;
  • 在边缘区域有一坐标轴分布较散,分布方向则根于图片的具体边缘的方向而定,如果边缘是水平或者垂直方向,那么Iy轴方向或者Ix方向上的数据分布就比较散;
  • 在角点区域,我们观察出来在x方向和y 方向都比较分散。那我们就可以认为某个像素点在窗口内当x方向和y 方向梯度的协方差都比较大,这个点的就可以当做为角点。

我们在来观察一下M的表达式是不是跟协方差矩阵形式很像,但是还是有些不同。一般协方差矩阵对应维的随机变量需要减去该维随机变量的均值,但矩阵M中并没有这样做,所以在矩阵M里,我们先进行各维的均值化处理,那么各维所对应的随机变量的均值为0,协方差矩阵就大大简化了,简化的最终结果就是矩阵M。 我们在坚持一下读下去,如果我们对协方差矩阵M进行对角化,很明显,特征值就是主分量上的方差。(对于这方面还有疑惑的,可以去看一下主成分分析pca相关的内容,然后推到一下公式) 所以我们就可以得出如下结论如图:



  • 两个特征值都比较大时,即窗口中含有角点
  • 特征值一个较大,一个较小,窗口中含有边缘
  • 两个特征值都比较小,窗口处在平坦区域

但是计算特征值还是比较耗时的,harris 通过启发式的思维,将计算特征值转换为计算度量角点响应R(这个怎么来的嘛,还是需要大量的数学经验的积累了)



k一般取0.04-0.06之间 至此,我们就可以通过判断一个像素点在窗口内的角点响应R,来判断是不是角点了,当R大于一定阈值,我们认为此像素点是角点,反之,则不是。



OpenCV 使用中harris角点检测效果[代码]

#include <iostream>
#include <opencv2/opencv.hpp>
int main(int argc, char *argv[])
{
    int blockSize = 2;
    int kSize = 3;
    double k = 0.04;
    double thread_value = 85;  // R的阈值

    cv::Mat  orignal_image = cv::imread (argv[1]);     
    cv::Mat gray_image , after_harris_image;
    cv::Mat norm_image; //归一化后的图
    cv::Mat scaled_image; //线性变换后的八位无符号整形的图
    cv::cvtColor (orignal_image,gray_image,CV_BGR2GRAY);     // 灰度变换
    cv::cornerHarris(gray_image, after_harris_image, blockSize, kSize, k, cv::BORDER_DEFAULT); //harris corner detect
    cv::normalize(after_harris_image, norm_image, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat()); //归一化处理
    convertScaleAbs(norm_image, scaled_image);
    for (int i = 0; i < norm_image.rows; i++)
    {
        for (int j = 0; j < norm_image.cols; j++)
        {
            if ((int)norm_image.at<float>(i, j) > thread_value)
            {
                cv::circle(orignal_image, cv::Point(j, i), 10, cv::Scalar(10, 10, 255), 1, 8, 0);  //tag the corner
            }
        }
    }
    cv::imshow("after_harris_corner", orignal_image);
    cv::imwrite("after_harris_corner.png",orignal_image);
    cv::waitKey(0);

    return 0;
}

下面是我自己选的一张图出来的效果,可以看到棋盘格标定板这种明显的角点还是很好的,包括椅子桌角也被检测出一些。





热烈庆祝第一篇成功写完,希望看到的同学们,如有问题,不吝赐教,小生立刻改正。❤


任何人或团体、机构全部转载或者部分转载、摘录,请保留本博客链接或标注来源。博客地址:开飞机的乔巴
作者简介:开飞机的乔巴(WeChat:zhangzheng-thu),现主要从事机器人抓取视觉系统以及三维重建等3D视觉相关方面,另外对slam以及深度学习技术也颇感兴趣,欢迎加我微信或留言交流相关工作。
发布于 2019-08-02 15:24