阅读(653) (0)

Harris corner检测器

2017-10-11 10:02:24 更新

目标

在本教程中,您将学习:

  • 什么功能和为什么它们是重要的
  • 使用函数cv :: cornerHarris使用Harris-Stephens方法检测corner。

理论

什么是功能?

  • 在计算机视觉中,通常我们需要在环境的不同帧之间找到匹配点。为什么?如果我们知道两个图像如何相互关联,我们可以使用这两个图像来提取它们的信息。
  • 当我们说匹配点时,我们在一般意义上指的是我们可以轻松识别的场景中的特征。我们称这些特征为特征。
  • 那么功能有什么特点呢?它必须是唯一可识别的

图像特征的类型

提到几个:

  • 边缘
  • 角(也称为兴趣点)
  • 斑点(也称为感兴趣区域)

在本教程中,我们将特别研究角落特征。

为什么角落如此特别?

  • 因为它是两个边的交点,它代表这两个边的方向改变的点。因此,图像的梯度(两个方向)具有高的变化,可用于检测它。

它是如何工作的?

  • 让我们来看看吧。由于角代表了图像中渐变的变化,我们将寻找这种“变化”。
  • 考虑一个灰度图像I。我们要扫一个窗口w(x,y)(x位移u和y方向的v)I我将计算强度的变化。

Harris corner检测器

where:

  1. w(x,y) is the window at position (x,y)
  2. I(x,y) is the intensity at (x,y)
  3. I(x+u,y+v) is the intensity at the moved window (x+u,y+v)
  • 由于我们正在寻找具有角落的窗户,所以我们正在寻找强度变化很大的窗户。因此,我们必须最大化上述方程,特别是术语:

Harris corner检测器

  • 使用泰勒扩展

Harris corner检测器

  • 扩大方程并正确取消:

Harris corner检测器

  • 其中可以以矩阵形式表示为:

Harris corner检测器

  • 可以表示为:

Harris corner检测器

  • 那么现在我们的方程是:

Harris corner检测器

  • 计算每个窗口的分数,以确定它是否可能包含一个角:

Harris corner检测器


where:

  1. det(M) = λ1λ2
  2. trace(M) = λ1+λ2

窗口R得分大于某一值的被认为是“corner”

Code

本教程代码如下所示。您也可以从这里下载

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat src, src_gray;
int thresh = 200;
int max_thresh = 255;
const char* source_window = "Source image";
const char* corners_window = "Corners detected";
void cornerHarris_demo( int, void* );
int main( int, char** argv )
{
  src = imread( argv[1], IMREAD_COLOR );
  cvtColor( src, src_gray, COLOR_BGR2GRAY );
  namedWindow( source_window, WINDOW_AUTOSIZE );
  createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );
  imshow( source_window, src );
  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 );
  int blockSize = 2;
  int apertureSize = 3;
  double k = 0.04;
  cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );
  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, WINDOW_AUTOSIZE );
  imshow( corners_window, dst_norm_scaled );
}

结果

原始图片:

Harris corner检测器

检测到的角落被一个小的黑色圆圈包围

Harris corner检测器