zoukankan      html  css  js  c++  java
  • OpenCV Harris 角点检测子

    Harris 角点检测子

    目标

    本教程中我们将涉及:

    • 有哪些特征?它们有什么用?
    • 使用函数 cornerHarris 通过 Harris-Stephens方法检测角点.

    理论

    有哪些特征?

    在计算机视觉中,我们通常需要寻找两张图上的匹配关键点。为什么?因为一旦我们知道了两张图是相关联的,我们就可以使用 *both 图像来提取它们中的信息。

    是指

    • 匹配关键点 是指在场景中可以很容易识别出来的 特性 . 这些特性就是这里所说的 特征 。
    • 因此,特征应该有什么样的特性呢?
      • 应该具有 可识别的独一无二性

    图像特征类型

    图像特征类型:

    • 边缘
    • 角点 (感兴趣关键点)
    • 斑点(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 egin{bmatrix}
                u & v
               end{bmatrix}
               left (
               displaystyle sum_{x,y}
               w(x,y)
               egin{bmatrix}
                I_x^{2} & I_{x}I_{y} \
                I_xI_{y} & I_{y}^{2}
               end{bmatrix}
               
ight )
               egin{bmatrix}
                u \
                v
               end{bmatrix}

    • 表示为:

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

    • 因此我们有等式:

      E(u,v) approx egin{bmatrix}
                u & v
               end{bmatrix}
               M
               egin{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 大于一个特定值,这个窗口就可以被认为是”角点”

    代码

    这个教程的代码如下所示。还可以通过 这个链接下载到源代码

    #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* );
    
    /** @function main */
    int main( int argc, char** argv )
    {
      /// Load source image and convert it to gray
      src = imread( argv[1], 1 );
      cvtColor( src, src_gray, CV_BGR2GRAY );
    
      /// Create a window and a trackbar
      namedWindow( source_window, CV_WINDOW_AUTOSIZE );
      createTrackbar( "Threshold: ", source_window, &thresh, max_thresh, cornerHarris_demo );
      imshow( source_window, src );
    
      cornerHarris_demo( 0, 0 );
    
      waitKey(0);
      return(0);
    }
    
    /** @function cornerHarris_demo */
    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;
    
      /// Detecting corners
      cornerHarris( src_gray, dst, blockSize, apertureSize, k, BORDER_DEFAULT );
    
      /// Normalizing
      normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
      convertScaleAbs( dst_norm, dst_norm_scaled );
    
      /// Drawing a circle around corners
      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 );
                  }
              }
         }
      /// Showing the result
      namedWindow( corners_window, CV_WINDOW_AUTOSIZE );
      imshow( corners_window, dst_norm_scaled );
    }
    

    解释

    实验结果

    原始图像:

    ../../../../../_images/Harris_Detector_Original_Image.jpg

    检测到的角点被黑色圈标记了

    ../../../../../_images/Harris_Detector_Result.jpg

    翻译者

    Shuai Zheng, <kylezheng04@gmail.com>, http://www.cbsr.ia.ac.cn/users/szheng/

    from: http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/features2d/trackingmotion/harris_detector/harris_detector.html#harris-detector

  • 相关阅读:
    表达式计算 java 后缀表达式
    动态规划略有所得 数字三角形(POJ1163)
    SharedPreferences的基本数据写入和读取
    安卓 io流 写入文件,再读取的基本使用
    SqLite的基本使用
    安卓手机开机开启指定Activity
    Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK fla
    广播的基本使用,判断是否有可用网络,并弹出设置窗口
    AsyncTask下载网络图片的简单应用
    Intellij_idea-14官方快捷键中文版
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/5292232.html
Copyright © 2011-2022 走看看