图像特征类型:
- 边缘:前面的文章已经涉及。
- 角点 (感兴趣关键点):两个边缘的连接点,它代表了两个边缘变化的方向上的点。图像梯度有很高的变化。这种变化是可以用来帮助检测角点的
- 斑点(Blobs) (感兴趣区域)
如何寻找角点:
-
由于角点代表了图像像素梯度变化,我们将寻找这个”变化”。
-
考虑到一个灰度图像
. 划动窗口
(with displacements
在x方向和
方向)
计算像素灰度变化。
其中:
is the window at position
is the intensity at
is the intensity at the moved window
-
为了寻找带角点的窗口,我们搜索像素灰度变化较大的窗口。于是, 我们期望最大化以下式子:
-
使用 泰勒(Taylor)展开式:
-
式子可以展开为:
-
一个举证表达式可以写为:
-
表示为:
-
因此我们有等式:
-
每个窗口中计算得到一个值。这个值决定了这个窗口中是否包含了角点:
其中:
- det(M) =
- trace(M) =
一个窗口,它的分数
大于一个特定值,这个窗口就可以被认为是”角点”
- det(M) =
用到的函数:
cornerHarris
void cornerHarris(InputArray src, OutputArray dst, int blockSize, int apertureSize, double k, int borderType=BORDER_DEFAULT )
Parameters: |
|
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:
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 )
{
}
void cornerHarris_demo( int, void* )
{
}
运行结果: