moravec corner detector ---角点检测算子

最近做一些特征检测方面的东西,用的opencv自带的一些算法surf++knn+ransac等,进行指定区域的识别和扣取。然而,对这个检测算子的理解一致不太深入。于是的于是呢,参考了《计算机视觉:算法与应用》后,决定对这个方向了解一下。第一个自然是前人最经典的杰作:moravec corner;

moravec corner 首先提取了8个以45°为步长的局部差方之和,然后在8个中选取最小的一个作为当前的特征值,具有一定程度上的旋转不变性。然会对这个特征值进行阈值判断,提取出角点。8个模板可以采用3*3 5*5 或者7*7;这里采用5*5的方法进行测试。



代码稍后奉上(只实现了大概流程,代码没有经过优化)

 
  
#pragma once
#include"opencv2/opencv.hpp"
#include 
class CMoravecCorner
{
private: 
	int winsize;
	int threshold;
	std::vector  corners;
public:
	CMoravecCorner(void);
	~CMoravecCorner(void);
	void set_thresold(int threshold)
	{
		this->threshold =threshold;
	}
	std::vector corner_detect(const cv::Mat img, int winsize=5)
	{
		//转换为灰度图
		cv::Mat src;
		cv::cvtColor(img,src,cv::COLOR_RGB2GRAY );
		int censize=winsize/2;
		for(int x=censize+1;x<(src.rows-censize-1);x++)
		{
			for(int y=censize+1;y<(src.cols-censize-1);y++)
			{
				//检测8个方向的特征(1,0),(1,1),(0,1)(-1,1),(-1,0),(-1,-1),(0,-1),(1,-1);
				float ssd[8]={0,0,0,0};
				//(1,0)方向特征
				for(int win_leng=-censize;win_leng<=censize;win_leng++)
				{
					for (int win_heig=-censize;win_heig<=censize;win_heig++)
					{
						ssd[0]+=pow((src.at(x+win_leng,y+win_heig)-src.at(x+1+win_leng,y+win_heig)),2);
					}
				}
				//(1,1)方向特征
				for(int win_leng=-censize;win_leng<=censize;win_leng++)
				{
					for (int win_heig=-censize;win_heig<=censize;win_heig++)
					{
						ssd[1]+=pow((src.at(x+win_leng,y+win_heig)-src.at(x+1+win_leng,y+1+win_heig)),2);
					}
				}
				//(0,1)方向特征
				for(int win_leng=-censize;win_leng<=censize;win_leng++)
				{
					for (int win_heig=-censize;win_heig<=censize;win_heig++)
					{
						ssd[2]+=pow((src.at(x+win_leng,y+win_heig)-src.at(x+win_leng,y+1+win_heig)),2);
					}
				}
				//(-1,1)方向特征
				for(int win_leng=-censize;win_leng<=censize;win_leng++)
				{
					for (int win_heig=-censize;win_heig<=censize;win_heig++)
					{
						ssd[3]+=pow((src.at(x+win_leng,y+win_heig)-src.at(x-1+win_leng,y+1+win_heig)),2);
					}
				}
				//(-1,0)方向特征
				for(int win_leng=-censize;win_leng<=censize;win_leng++)
				{
					for (int win_heig=-censize;win_heig<=censize;win_heig++)
					{
						ssd[4]+=pow((src.at(x+win_leng,y+win_heig)-src.at(x-1+win_leng,y+win_heig)),2);
					}
				}
				//(-1,-1)方向特征
				for(int win_leng=-censize;win_leng<=censize;win_leng++)
				{
					for (int win_heig=-censize;win_heig<=censize;win_heig++)
					{
						ssd[5]+=pow((src.at(x+win_leng,y+win_heig)-src.at(x-1+win_leng,y+win_heig-1)),2);
					}
				}
				//(0,-1)方向特征
				for(int win_leng=-censize;win_leng<=censize;win_leng++)
				{
					for (int win_heig=-censize;win_heig<=censize;win_heig++)
					{
						ssd[6]+=pow((src.at(x+win_leng,y+win_heig)-src.at(x+win_leng,y+win_heig-1)),2);
					}
				}
				//(1,-1)方向特征
				for(int win_leng=-censize;win_leng<=censize;win_leng++)
				{
					for (int win_heig=-censize;win_heig<=censize;win_heig++)
					{
						ssd[7]+=pow((src.at(x+win_leng,y+win_heig)-src.at(x+1+win_leng,y+win_heig-1)),2);
					}
				}
				//提取最小特征
				float minvalue=ssd[0];
				for(int i=0;i<8;i++)
				{
					minvalue=minvaluethreshold)
				{
					corners.push_back(cv::Point(y,x));
				}
				/*else continue;*/

			}
		}
		std::cout<::const_iterator it=corners.begin ();
		for(;it!=corners.end();it++)
		{
			cv::circle(src,*it,3,cv::Scalar(255,0,0),2);
		}
		//cv::imshow("temp",src);  //显示结果

	}
};


 
 

你可能感兴趣的:(opencv,特征检测算子)