示例程序041--Harris 角点检测子

图像特征类型:

  • 边缘:前面的文章已经涉及。
  • 角点 (感兴趣关键点):两个边缘的连接点,它代表了两个边缘变化的方向上的点。图像梯度有很高的变化。这种变化是可以用来帮助检测角点的
  • 斑点(Blobs) (感兴趣区域)

如何寻找角点:

  • 由于角点代表了图像像素梯度变化,我们将寻找这个”变化”。

  • 考虑到一个灰度图像 I . 划动窗口 w(x,y) (with displacements u 在x方向和 v 方向) I 计算像素灰度变化。

    E(u,v) = \sum _{x,y} w(x,y)[ I(x+u,y+v) - I(x,y)]^{2}

    其中:

    • w(x,y) is the window at position (x,y)
    • I(x,y) is the intensity at (x,y)
    • I(x+u,y+v) is the intensity at the moved window (x+u,y+v)
  • 为了寻找带角点的窗口,我们搜索像素灰度变化较大的窗口。于是, 我们期望最大化以下式子:

    \sum _{x,y}[ I(x+u,y+v) - I(x,y)]^{2}

  • 使用 泰勒(Taylor)展开式:

    E(u,v) \approx \sum _{x,y}[ I(x,y) + u I_{x} + vI_{y} - I(x,y)]^{2}

  • 式子可以展开为:

    E(u,v) \approx \sum _{x,y} u^{2}I_{x}^{2} + 2uvI_{x}I_{y} + v^{2}I_{y}^{2}

  • 一个举证表达式可以写为:

    E(u,v) \approx \begin{bmatrix} u & v \end{bmatrix} \left ( \displaystyle \sum_{x,y} w(x,y) \begin{bmatrix} I_x^{2} & I_{x}I_{y} \\ I_xI_{y} & I_{y}^{2} \end{bmatrix} \right ) \begin{bmatrix} u \\ v \end{bmatrix}

  • 表示为:

    M = \displaystyle \sum_{x,y} w(x,y) \begin{bmatrix} I_x^{2} & I_{x}I_{y} \\ I_xI_{y} & I_{y}^{2} \end{bmatrix}

  • 因此我们有等式:

    E(u,v) \approx \begin{bmatrix} u & v \end{bmatrix} M \begin{bmatrix} u \\ v \end{bmatrix}

  • 每个窗口中计算得到一个值。这个值决定了这个窗口中是否包含了角点:

    R = det(M) - k(trace(M))^{2}

    其中:

    • det(M) = \lambda_{1}\lambda_{2}
    • trace(M) = \lambda_{1}+\lambda_{2}

    一个窗口,它的分数 R 大于一个特定值,这个窗口就可以被认为是”角点”

用到的函数:

cornerHarris

void cornerHarris(InputArray src, OutputArray dst, int blockSize, int apertureSize, double k, int borderType=BORDER_DEFAULT )

Parameters:

  • src – Input single-channel 8-bit or floating-point image.
  • dst – Image to store the Harris detector responses. It has the type CV_32FC1 and the same size as src .
  • blockSize – Neighborhood size (see the details on cornerEigenValsAndVecs() ).
  • apertureSize – Aperture parameter for the Sobel() operator.
  • k – Harris detector free parameter. See the formula below.
  • boderType – Pixel extrapolation method. See borderInterpolate() .

The function runs the Harris edge detector on the image. Similarly to cornerMinEigenVal() and cornerEigenValsAndVecs() , for each pixel it calculates a gradient covariance matrix over a neighborhood. Then, it computes the following characteristic:

\texttt{dst} (x,y) = \mathrm{det} M^{(x,y)} - k \cdot \left ( \mathrm{tr} M^{(x,y)} \right )^2

 

Corners in the image can be found as the local maxima of this response map.

该函数将角点检测子存入dst矩阵,矩阵中的检测子若大于阈值则认为是角点。

 

程序代码及注释:

// 049 角点检测.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

 

/// Global variables
Mat src, src_gray;
int thresh = 200;
int max_thresh = 255;

char* source_window = "Source image";
char* corners_window = "Corners detected";

 

/// Function header
void cornerHarris_demo( int, void* );

 

int main( int argc, char** argv )
{
 //读入图像并转灰度
  src=imread("corner.jpg");
   imshow( source_window, src );

 

  cvtColor( src, src_gray, CV_BGR2GRAY );

 

   namedWindow( source_window, CV_WINDOW_AUTOSIZE );

 

 /// Create a window and a trackbar

  createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );


  cornerHarris_demo( 0, 0 );

 
  waitKey(0);
  return(0);
}


void cornerHarris_demo( int, void* )
{

  Mat dst, dst_norm, dst_norm_scaled;
  dst = Mat::zeros( src.size(), CV_32FC1 );

 

  /// Detector parameters
  int blockSize = 2;
  int apertureSize = 3;
  double k = 0.04;

 

  /// 角点检测子存储到dst矩阵
  cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );

 

  /// 归到[0,255]
  normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
  convertScaleAbs( dst_norm, dst_norm_scaled );   //取整


  for( int j = 0; j < dst_norm.rows ; j++ )
     { for( int i = 0; i < dst_norm.cols; i++ )
          {
            if( (int) dst_norm.at<float>(j,i) > thresh )        //若角点检测子大于阈值,画圈标注
              {
               circle( dst_norm_scaled, Point( i, j ), 5,  Scalar(0), 2, 8, 0 );
              }
          }
     }
 

  namedWindow( corners_window, CV_WINDOW_AUTOSIZE );
  imshow( corners_window, dst_norm_scaled );
}

运行结果:

示例程序041--Harris <wbr>角点检测子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值