.. _harris_detector: Harris 角点检测子 ********************** 目标 ===== 本教程中我们将涉及: .. container:: enumeratevisibleitemswithsquare * 有哪些特征?它们有什么用? * 使用函数 :corner_harris:`cornerHarris <>` 通过 Harris-Stephens方法检测角点. 理论 ====== 有哪些特征? ------------------- .. container:: enumeratevisibleitemswithsquare *在计算机视觉中,我们通常需要寻找两张图上的匹配关键点。为什么?因为一旦我们知道了两张图是相关联的,我们就可以使用 *both* 图像来提取它们中的信息。 是指 * **匹配关键点** 是指在场景中可以很容易识别出来的 *特性* . 这些特性就是这里所说的 **特征** 。 * **因此,特征应该有什么样的特性呢?** * 应该具有 *可识别的独一无二性* 图像特征类型 ------------------------ 图像特征类型: .. container:: enumeratevisibleitemswithsquare * 边缘 * **角点** (感兴趣关键点) * 斑点(Blobs) (感兴趣区域) 本教程涉及 *角点* 特征。 为什么角点是特殊的? ---------------------------- .. container:: enumeratevisibleitemswithsquare * 因为角点是两个边缘的连接点,它代表了两个边缘变化的方向上的点。图像梯度有很高的变化。这种变化是可以用来帮助检测角点的。 如何工作? ----------------- .. container:: enumeratevisibleitemswithsquare * 由于角点代表了图像像素梯度变化,我们将寻找这个"变化"。 * 考虑到一个灰度图像 :math:`I`. 划动窗口 :math:`w(x,y)` (with displacements :math:`u` 在x方向和 :math:`v` 方向) :math:`I` 计算像素灰度变化。 .. math:: E(u,v) = \sum _{x,y} w(x,y)[ I(x+u,y+v) - I(x,y)]^{2} 其中: * :math:`w(x,y)` is the window at position :math:`(x,y)` * :math:`I(x,y)` is the intensity at :math:`(x,y)` * :math:`I(x+u,y+v)` is the intensity at the moved window :math:`(x+u,y+v)` * 为了寻找带角点的窗口,我们搜索像素灰度变化较大的窗口。于是, 我们期望最大化以下式子: .. math:: \sum _{x,y}[ I(x+u,y+v) - I(x,y)]^{2} * 使用 *泰勒(Taylor)展开式*: .. math:: E(u,v) \approx \sum _{x,y}[ I(x,y) + u I_{x} + vI_{y} - I(x,y)]^{2} * 式子可以展开为: .. math:: E(u,v) \approx \sum _{x,y} u^{2}I_{x}^{2} + 2uvI_{x}I_{y} + v^{2}I_{y}^{2} * 一个举证表达式可以写为: .. math:: 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} * 表示为: .. math:: 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} * 因此我们有等式: .. math:: E(u,v) \approx \begin{bmatrix} u & v \end{bmatrix} M \begin{bmatrix} u \\ v \end{bmatrix} * 每个窗口中计算得到一个值。这个值决定了这个窗口中是否包含了角点: .. math:: R = det(M) - k(trace(M))^{2} 其中: * det(M) = :math:`\lambda_{1}\lambda_{2}` * trace(M) = :math:`\lambda_{1}+\lambda_{2}` 一个窗口,它的分数 :math:`R` 大于一个特定值,这个窗口就可以被认为是"角点" 代码 ==== 这个教程的代码如下所示。还可以通过 `这个链接下载到源代码 `_ .. code-block:: cpp #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include #include #include 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(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 ); } 解释 ============ 实验结果 ============ 原始图像: .. image:: images/Harris_Detector_Original_Image.jpg :align: center 检测到的角点被黑色圈标记了 .. image:: images/Harris_Detector_Result.jpg :align: center 翻译者 =============== Shuai Zheng, , http://www.cbsr.ia.ac.cn/users/szheng/