SIFT特征提取

SIFT特征提取步骤:
http://blog.csdn.net/abcjennifer/article/details/7639681
(1)构建金字塔尺度图
(2)获取特征点(极值点)
(3)去除不好的特征点
(4)对每个特征点计算128维参数
(5)特征点match

1.首先需要介绍一下DOG(高斯差分卷积)

这里写图片描述

2.极值点:若像素点是其相邻像素点(相邻层的像素点也算,一共28个)的极大值或者极小值,则该点位特征点。
这里写图片描述

3.不好的点的去除:这里使用Harris Corners检测器
1)根据泰勒展开式求极值点,根据阈值判断是否可以留下来
2)边界响应的去除:根据Hessian矩阵去除。

4.计算内个特征点周围16*16矩阵内的像素点的梯度方向和梯度模,再将该16*16矩阵划分为4*4的子矩阵,共16个。
这里写图片描述
这样就可以对每个feature形成一个4*4*8=128维的描述子,每一维都可以表示4*4个格子中一个的scale/orientation. 将这个向量归一化之后,就进一步去除了光照的影响。

  1. match :根据来那个户图像特征点的欧氏距离进行匹配。
    c代码实现
// FeatureDetector.cpp : Defines the entry point for the console application.
//  
//  Created by Rachel on 14-1-12.  
//  Copyright (c) 2013年 ZJU. All rights reserved.  
//  

#include "stdafx.h"
#include "highgui.h"
#include "cv.h"
#include "vector"
#include "opencv\cxcore.hpp"
#include "iostream"
#include "opencv.hpp"
#include "nonfree.hpp"
#include "showhelper.h"

using namespace cv;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    //Load Image 
    Mat c_src1 =  imread( "..\\Images\\3.jpg");
    Mat c_src2 = imread("..\\Images\\4.jpg");
    Mat src1 = imread( "..\\Images\\3.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    Mat src2 = imread( "..\\Images\\4.jpg", 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(280,230),&font,CV_RGB(255,0,0));//在图片中输出字符 

    str = str2;
    cvPutText(transimg2,str2,cvPoint(280,230),&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);
    cvWaitKey();
    cvDestroyAllWindows();

    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值