Harris角点检测

       在计算机视觉中,角点是图像比较重要的特征,对图像图形的理解和分析有很重要的作用,在保留图像图形重要特征的同时,可以代替整幅图像的处理,有效地减少信息的数据量,使其信息的含量很高,有效地提高了计算的速度,有利于图像的可靠匹配。所以角点检测也是计算机视觉中比较重要的一块,在目标识别,图像匹配,视觉跟踪,3D重建,全景图像拼接等领域都有应用。角点又称特征点或兴趣点,定义:窗口向任意方向的移动都将导致图像灰度的明显变化。具体有如下几种描述:

  • 一阶导数(即灰度的梯度)的局部最大所对应的像素点;
  • 两条及两条以上边缘的交点;
  • 图像中梯度值和梯度方向的变化速率都很高的点;
  • 角点处的一阶导数最大,二阶导数为零,指示物体边缘变化不连续的方向。

        角点检测方法有很多种,主要分三大类:基于灰度图像的角点检测、基于二值图像的角点检测、基于轮廓曲线的角点检测。基于灰度图像的角点检测又可分为基于梯度、基于模板和基于模板梯度组合3类方法,其中基于模板的方法主要考虑像素领域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点。Harris角点检测算法就是常见的基于模板的角点检测算法的一种。        

        Harris 角点最初由C.Harris和J.Stephens 于1988年A combined corner and edge detector 一文中提出,该文实际上是对Moravec 算法思想的改进。Harris角点最直观的解释是在两个相互垂直的方向,都有较大变化的点,代表图像梯度的变化。

将图像窗口平移[u,v],产生灰度变化 E[u,v]:


其中w(x,y)是窗口的位置,I(x,y)是密度,I(x+u,y+v)是窗口移动后的密度。

泰勒展开式:

代入E(u,v) 中,相减后平方展开,表示成矩阵的形式:

在这里令

   

所以有: 

对于每一个窗口,计算一个值

即矩阵的值和矩阵的迹平方的 k 倍相减的差值。k 的经验取值为0.04-0.06。

两特征值的大小和所检测到的范围的关系如下所示:

Harris角点检测_第1张图片

【代码】

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

using namespace cv;
using namespace std;

Mat src, src_gray;
int thresh = 100;
int max_thresh = 255;

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

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 );
			}
		}
	}
	namedWindow( corners_window, CV_WINDOW_AUTOSIZE );
	imshow( corners_window, dst_norm_scaled );
	waitKey(30);
}

int main( int argc, char** argv )
{
	src = imread( "car.png", 1 );
	cvtColor( src, src_gray, CV_BGR2GRAY );

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

	imshow( source_window, src );
	waitKey(30);
	cornerHarris_demo( 0, 0 );

	waitKey(0);
	return(0);
}

运行结果图:

Harris角点检测_第2张图片

你可能感兴趣的:(opencv,harris)