MATLAB实现图像的SIFT特征提取源码

function [frames,descriptors,scalespace,difofg]=do_sift(I,varargin)
%% file:       sift.m
% author:      Noemie Phulpin
% description: SIFT algorithm

warning off all;

[M,N,C] = size(I) ;

% Lowe's choices
S=3 ;
omin= 0 ;
%O=floor(log2(min(M,N)))-omin-4 ; % Up to 16x16 images
O = 4;

sigma0=1.6*2^(1/S) ;
sigmaN=0.5 ;
thresh = 0.2 / S / 2 ; % 0.04 / S / 2 ;
r = 18 ;

NBP = 4 ;
NBO = 8 ;
magnif = 3.0 ;

% Parese input
compute_descriptor = 0 ;
discard_boundary_points = 1 ;
verb = 0 ;

% Arguments sanity check
if C > 1
  error('I 应该是灰度图') ;
end

frames = [] ;
descriptors = [] ;


%   开始工作
%
fprintf('---------------------------- 开始 SIFT: 从图像中提取SIFT特征 ------------------------------\n') ; tic ; 

fprintf('SIFT: 用DoG构造尺度空间 ...\n') ; tic ; 

scalespace = do_gaussian(I,sigmaN,O,S,omin,-1,S+1,sigma0) ;

fprintf('                高斯尺度空间计时: (%.3f s)\n',toc) ; tic ; 

difofg = do_diffofg(scalespace) ;

fprintf('                构建相减尺度空间: (%.3f s)\n',toc) ;

for o=1:scalespace.O
    
    
    fprintf('CS5240 -- SIFT: 计算 “组”  %d\n', o-1+omin) ;
                tic ;
    
  %  DOG octave 的局部极值检测
    oframes1 = do_localmax(  difofg.octave{o}, 0.8*thresh, difofg.smin  ) ;
    oframes2 = do_localmax( -difofg.octave{o}, 0.8*thresh, difofg.smin  ) ;
    oframes = [oframes1 ,oframes2 ] ; 
    
    
    fprintf('CS5240 -- SIFT: 初始化关键点 # %d.  \n', ...
      size(oframes, 2)) ;
    fprintf('                用时 (%.3f s)\n', ...
       toc) ;
    tic ;
    
    if size(oframes, 2) == 0
        continue;
    end
    
  % 移除靠近边界的关键点
    rad = magnif * scalespace.sigma0 * 2.^(oframes(3,:)/scalespace.S) * NBP / 2 ;
    sel=find(...
      oframes(1,:)-rad >= 1                     & ...
      oframes(1,:)+rad <= size(scalespace.octave{o},2) & ...
      oframes(2,:)-rad >= 1                     & ...
      oframes(2,:)+rad <= size(scalespace.octave{o},1)     ) ;
    oframes=oframes(:,sel) ;%把不是靠近边界点的极值点重新放入oframes中
        
    fprintf('CS5240 -- SIFT: 移除靠近边界关键点后 # %d \n', size(oframes,2)) ;
      tic ;
        
  % 精简局部, 阈值强度 和移除边缘关键点
       oframes = do_extrefine(...
         oframes, ...
         difofg.octave{o}, ...
         difofg.smin, ...
         thresh, ...
         r) ;
   
       fprintf('CS5240 -- SIFT:  移除低对比度和边缘上关键点后 # %d \n',size(oframes,2)) ;
    fprintf('                Time (%.3f s)\n',  toc) ;
    tic ;
  
    fprintf('CS5240 -- SIFT: 计算特征点方向\n');

  % 计算方向
    oframes = do_orientation(...
        oframes, ...
        scalespace.octave{o}, ...
        scalespace.S, ...
        scalespace.smin, ...
        scalespace.sigma0 ) ;
    fprintf('                用时: (%.3f s)\n', toc);tic;
        
  % Store frames
    x     = 2^(o-1+scalespace.omin) * oframes(1,:) ;
    y     = 2^(o-1+scalespace.omin) * oframes(2,:) ;
    sigma = 2^(o-1+scalespace.omin) * scalespace.sigma0 * 2.^(oframes(3,:)/scalespace.S) ;    %图像的尺度    
    frames = [frames, [x(:)' ; y(:)' ; sigma(:)' ; oframes(4,:)] ] ;

    fprintf('CS5240 -- SIFT:计算方向后的特征点 # %d  \n', size(frames,2)) ;
  % Descriptors
    
    fprintf('CS5240 -- SIFT: 计算 描述子...\n') ;
    tic ;
        
    sh = do_descriptor(scalespace.octave{o}, ...
                    oframes, ...
                    scalespace.sigma0, ...
                    scalespace.S, ...
                    scalespace.smin, ...
                    'Magnif', magnif, ...
                    'NumSpatialBins', NBP, ...
                    'NumOrientBins', NBO) ;
    
    descriptors = [descriptors, sh] ;%每一组计算描述子向量后补充到descriptors数组中
    
    fprintf('                用时: (%.3f s)\n\n\n',toc) ; 
    
      
    
end 

fprintf('CS5240 -- SIFT: 关键点总数: %d \n\n\n', size(frames,2)) ;
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fpga和matlab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值