特征检测和描述(SIFT)

特征检测和描述(SIFT)


SIFT(Scale Invariant FeatureTransform),SIFT摘自《Distinctive Image Features from Scale-Invariant Keypoints》这篇文章。

Following are the major stages of computation used to generate the set of image features:

(1)Scale-space extrema detection(尺度空间极值检测).

It is implemented efficiently by using a difference-of-Gaussian function to identify potential interest points that are invariant to scale and orientation.

(2)Keypoint localization(关键点定位).

Keypoints are selected based on measures of their stability.

(3)Orientation assignment(方向分配).

One or more orientations are assigned to each keypoint location based on local image gradient directions.
(4)Keypoint descriptor(关键点描述子).


1、opencv的文档

SIFT定义在#include <opencv2/nonfree/features2d.hpp>


class SIFT : public Feature2D
Class for extracting keypoints and computing descriptors using the Scale Invariant Feature Transform (SIFT) algorithm by D. Lowe [Lowe04].
Lowe, D. G., “Distinctive Image Features from Scale-Invariant Keypoints”, International Journal of Computer Vision, 60, 2, pp. 91-110, 2004.

2、opencv源码定义

/*!
 SIFT implementation.

 The class implements SIFT algorithm by D. Lowe.
*/
class CV_EXPORTS_W SIFT : public Feature2D
{
public:
    CV_WRAP explicit SIFT( int nfeatures=0, int nOctaveLayers=3,
          double contrastThreshold=0.04, double edgeThreshold=10,
          double sigma=1.6);

    //! returns the descriptor size in floats (128)
    CV_WRAP int descriptorSize() const;

    //! returns the descriptor type
    CV_WRAP int descriptorType() const;

    //! finds the keypoints using SIFT algorithm
    void operator()(InputArray img, InputArray mask,
                    vector<KeyPoint>& keypoints) const;
    //! finds the keypoints and computes descriptors for them using SIFT algorithm.
    //! Optionally it can compute descriptors for the user-provided keypoints
    void operator()(InputArray img, InputArray mask,
                    vector<KeyPoint>& keypoints,
                    OutputArray descriptors,
                    bool useProvidedKeypoints=false) const;

    AlgorithmInfo* info() const;

    void buildGaussianPyramid( const Mat& base, vector<Mat>& pyr, int nOctaves ) const;
    void buildDoGPyramid( const vector<Mat>& pyr, vector<Mat>& dogpyr ) const;
    void findScaleSpaceExtrema( const vector<Mat>& gauss_pyr, const vector<Mat>& dog_pyr,
                                vector<KeyPoint>& keypoints ) const;

protected:
    void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
    void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;

    CV_PROP_RW int nfeatures;
    CV_PROP_RW int nOctaveLayers;
    CV_PROP_RW double contrastThreshold;
    CV_PROP_RW double edgeThreshold;
    CV_PROP_RW double sigma;
};

typedef SIFT SiftFeatureDetector;
typedef SIFT SiftDescriptorExtractor;

3、实例应用

(1)代码:

#include <opencv2/opencv.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
	//Load Image   
	Mat c_src1 =  imread( "1.png");  
	Mat c_src2 = imread("2.png");  
	Mat src1 = imread( "1.png", CV_LOAD_IMAGE_GRAYSCALE);  
	Mat src2 = imread( "2.png", CV_LOAD_IMAGE_GRAYSCALE);  
	if( !src1.data || !src2.data )  
			std::cout<< " --(!) Error reading images " << std::endl; return -1; 
	}  

	//sift feature detect  
	SiftFeatureDetector detector;  
	std::vector<KeyPoint> kp1, kp2;  

	detector.detect( src1, kp1 );  
	detector.detect( src2, kp2 );  
	SiftDescriptorExtractor extractor;  
	Mat des1,des2;//descriptor  
	extractor.compute(src1,kp1,des1);  
	extractor.compute(src2,kp2,des2);     
	Mat res1,res2;   
	int drawmode = DrawMatchesFlags::DRAW_RICH_KEYPOINTS;  
	drawKeypoints(c_src1,kp1,res1,Scalar::all(-1),drawmode); //在内存中画出特征点  
	drawKeypoints(c_src2,kp2,res2,Scalar::all(-1),drawmode);  
	cout<<"size of description of Img1: "<<kp1.size()<<endl;  
	cout<<"size of description of Img2: "<<kp2.size()<<endl;  

	//write the size of features on picture  
	CvFont font;      
	double hScale=1;     
	double vScale=1;      
	int lineWidth=2;	// 相当于写字的线条      
	cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth); //初始化字体,准备写到图片上的     
	//cvPoint 为起笔的x,y坐标     
	IplImage* transimg1 = cvCloneImage(&(IplImage) res1);  
	IplImage* transimg2 = cvCloneImage(&(IplImage) res2);  

	char str1[20],str2[20];  
	sprintf(str1,"%d",kp1.size());  
	sprintf(str2,"%d",kp2.size());  



	const char* str = str1;  
	cvPutText(transimg1,str1,cvPoint(40,130),&font,CV_RGB(255,0,0));//在图片中输出字符   

	str = str2;  
	cvPutText(transimg2,str2,cvPoint(40,130),&font,CV_RGB(255,0,0));//在图片中输出字符   

	//imshow("Description 1",res1);  
	cvShowImage("descriptor1",transimg1);  
	cvShowImage("descriptor2",transimg2);  

	BFMatcher matcher(NORM_L2);  
	vector<DMatch> matches;  
	matcher.match(des1,des2,matches);  
	Mat img_match;  
	drawMatches(src1,kp1,src2,kp2,matches,img_match);//,Scalar::all(-1),Scalar::all(-1),vector<char>(),drawmode);  
	cout<<"number of matched points: "<<matches.size()<<endl;  
	imshow("matches",img_match);  
	waitKey(0);
	return 0;
}

(2)运行效果

原始图像


效果图


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值