图像特征之harris角点

harris算子也称为Plessey算子,是为了改善Moravec算子性能,由Harris和Stephens提出的。经典的Harris角点检测是基于亮度变化的角点检测算法,具有较高的稳定性和稳健性,能够在图像旋转,灰度变化以及噪声干扰等情况下准确的检测到角点。

它的计算步骤如下:

1.首先计算矩阵M


其中Ix是图像该点对x方向的偏导数,Iy是对y方向的偏导数,w是你所选择的邻域,可以是3*3或者是5*5等等都可以。这个矩阵是一个实对称矩阵,它有两个特征值,如果这两个特征值都比较大,那么该点就是角点;如果一个大一个小,那么该点就是边缘点;如果都比较小,就说明该点的灰度变化比较平缓,是一个平面。

2.在角点判别中,一般不需要计算两个特征值,而是采用角点响应函数R作为检测角点特征的依据:


根据响应值R的大小可以区分出图像中的边缘和角点,所以可以在这里设置一个阈值来判断该点是否为角点,阈值提高,可以减少检测到的角点数目。邻域大小的改变会影响提取角点的数目和容忍度,通常在3*3或5*5的邻域内进行非极大抑制,局部极大值即为图像中的角点。

我用opencv2.3.1+vs2008实现的代码如下:

#include "stdafx.h"  
   
#include <opencv2/opencv.hpp>  
#include "highgui.h"  
#include <math.h>  
typedef  unsigned long uint32;
typedef  unsigned int  uint16;
typedef  unsigned char uint8;
#define THRESHOLD  5
IplImage *src_gray1, *src_gray2, *src_gray3;    
IplImage* src_img, *dst_img;

void AllocateImage(IplImage* I)   //给图像分配大小    
{    
    CvSize sz   = cvGetSize(I);    
    
	dst_img   = cvCreateImage( sz, IPL_DEPTH_8U, 1);
	cvSetZero(dst_img);
    src_gray1 = cvCreateImage( sz, IPL_DEPTH_8U, 1);    //原图的三个通道    
    src_gray2 = cvCreateImage( sz, IPL_DEPTH_8U, 1);    
    src_gray3 = cvCreateImage( sz, IPL_DEPTH_8U, 1);       
    
}  

void DeallocateImage()
{
	cvReleaseImage(&src_img);  
    cvReleaseImage(&src_gray1);  
    cvReleaseImage(&src_gray2);  
    cvReleaseImage(&src_gray3);  


}
 
void Harris_check(IplImage* I, IplImage* dst, int n)                    //harris角点检测函数
{
	int i,j,x,y,num;
	int Value,ValueX0,ValueY0;
	int IX,IY;
	long M00,M01,M11;
	double DetM,TraceM;
	double *R = new double[I->width*I->height];
	for( i=1+n/2; i<(I->height-1-n/2); i++ )               //计算角点响应函数R
	{
		for( j=1+n/2; j<(I->width-1-n/2); j++ )
		{
			M00=0;
			M01=0;
			M11=0;
			for( y=0; y<n; y++ )
			{
				for( x=0; x<n; x++ )
				{
					Value   = *( I->imageData + (i-n/2+y)*I->widthStep + (j-n/2+x) );
					ValueX0 = *( I->imageData + (i-n/2+y)*I->widthStep + (j-n/2+x-1) );
					ValueY0 = *( I->imageData + (i-n/2+y-1)*I->widthStep + (j-n/2+x) );
					IX = Value - ValueX0;
					IY = Value - ValueY0;
					M00 += IX*IX;
					M01 += IX*IY;
					M11 += IY*IY;
				}
			}
			DetM = M00*M11 - M01*M01;
			TraceM = M00 + M11;
			R[i*I->width+j] = DetM - 0.05*TraceM*TraceM;
			
		}
	}
	for( i=1+n/2; i<(I->height-1-n/2); i++ )             //非极大抑制
	{
		for( j=1+n/2; j<(I->width-1-n/2); j++ )
		{
			if( R[i*I->width+j]>THRESHOLD)
			{
				num=0;
				for(y=0; y<n; y++)
				{
					for(x=0; x<n; x++)
					{
						if(R[i*I->width+j]>R[(i-n/2+y)*I->width+j-n/2+x])
						num++;
					}
				}
				if(num==n*n-1)
				{
				*(dst->imageData+i*dst->widthStep+j) =255;
				}
			}
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	src_img  = cvLoadImage("角点.bmp");
	AllocateImage(src_img);
	cvSplit( src_img, src_gray1, src_gray2, src_gray3, 0); 


	Harris_check(src_gray1, dst_img, 5);

	cvNamedWindow("my picture",CV_WINDOW_AUTOSIZE); 
	cvNamedWindow("my dst",CV_WINDOW_AUTOSIZE);  

	cvShowImage("my picture",src_img);  
	cvShowImage("my dst",dst_img); 

	cvWaitKey(0);  
    DeallocateImage();
	cvDestroyWindow("my picture");  
	cvDestroyWindow("my dst"); 
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值