天天看点

OpenCV教程(43) harris角的检测(1)

      计算机视觉中,我们经常要匹配两幅图像。匹配的的方式就是通过比较两幅图像中的公共特征,比如边,角,以及图像块(blob)等,来对两幅图像进行匹配。

     相对于边,角更适合描述图像特征,比如下面的图像中,大概有6种特征,我们用A、B、C、D、E、F来描述,其中A, B是平的区域,在图像中很难精确定位,C,D是边,比A,B好些,但是图像中的边也很多,定位到某个边也比较困难,相比来说E,F的角更适合描述当前的图像的特征,也更好检测,因为你不论怎么移动图像,这些角的特征都和图像其它部分不同。所以在计算机视觉中,我们通常用角来描述图像特征。

OpenCV教程(43) harris角的检测(1)

E,F中的角我们通常称作角点(corner points),他们具有以下特征:

–局部窗口沿各方向移动,均产生明显变化的点

–图像局部曲率突变的点

OpenCV教程(43) harris角的检测(1)

      在这篇教程中,我们来学习如何在图像中检测harrs特征角,harris特征角最早在paper A Combined Corner and Edge Detector中被Chris Harris & Mike Stephens提出。

     Harris角点检测的基本思想:从图像局部的小窗口观察图像特征,在各个方向移动都会导致图像灰度的明显变化,也就是说图像的梯度在各个方向有很大变化。

OpenCV教程(43) harris角的检测(1)

      下面我们看看harris角的计算方法:

OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)

     由于我们要在一个窗口内查找harris特征角,所以我们必须找到变化最大的窗口,这个窗口内肯定存在特征角,所以我们定义下面的方程,并用泰勒级数展开式子:

OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)

表示成矩阵乘法形式:

OpenCV教程(43) harris角的检测(1)

假设

OpenCV教程(43) harris角的检测(1)

则有:

OpenCV教程(43) harris角的检测(1)

对每一个窗口计算得到一个分数R,根据R的大小来判定窗口内是否存在harris特征角。分数R根据下面公式计算得到:

OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)
OpenCV教程(43) harris角的检测(1)

在opencv中,我们可以通过函数cv::cornerHarris 计算特征角,

C++: void cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, intborderType=BORDER_DEFAULT )

Parameters:

src – 单通道8位或者浮点图像。

dst – 存储 Harris 角的结果图像,它的格式为:CV_32FC1,图像大小和源图像一致。

blockSize – 就是扫描时候窗口的大小。

k – 上面介绍的计算R时候的k参数值。

borderType –像素插值方法。

下面的代码显示一副图像的harris角检测结果:

// 读入输入图像

cv::Mat image= cv::imread("../church01.jpg",0);

if (!image.data)

    return 0;

// 显示图像

cv::namedWindow("Original Image");

cv::imshow("Original Image",image);

// 检测 Harris Corners

cv::Mat cornerStrength;

cv::cornerHarris(image,cornerStrength,

    3,     // neighborhood size

    3,     // aperture size

    0.01); // Harris parameter

//二值化harris角的检测结果

cv::Mat harrisCorners;

double threshold= 0.0001;

cv::threshold(cornerStrength,harrisCorners,

    threshold,255,cv::THRESH_BINARY_INV);

// 显示结果

cv::namedWindow("Harris Corner Map");

cv::imshow("Harris Corner Map",harrisCorners);

下面是程序的运行结果:

OpenCV教程(43) harris角的检测(1)

程序代码:参考工程文件FirstOpenCV48

继续阅读