特征提取-SIFT特征源码解析

79 篇文章 12 订阅
57 篇文章 2 订阅

环境:matlab2012a

源码作者如下:

% This m-file demoes the usage of SIFT functions. It generates SIFT keypionts and descriptors for one input image. 
% Author: Yantao Zheng. Nov 2006.  For Project of CS5240

%% file:        do_gaussian.m
 % author:      Noemie Phulpin
 % description: gaussian scale space of image I

SIFT变换函数流程如下:

[frames1,descr1,gss1,dogss1] = do_sift( I1, 'Verbosity', 1, 'NumOctaves', 4, 'Threshold',  0.1/3/2 ) ; %0.04/3/2

接下来看do_sift函数:

第一步:首先初始化一些变量:

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 should be a grayscale image') ;
end

frames = [] ;
descriptors = [] ;
第二步:开始构建尺度空间

fprintf('CS5240 -- SIFT: constructing scale space with DoG ...\n') ; tic ; 

scalespace = do_gaussian(I,sigman,O,S,omin,-1,S+1,sigma0) ;
进入do_gaussian 函数:

开始 Gaussian scale space construction:

function L = do_gaussian(I,sigman,O,S,omin,smin,smax,sigma0)

%% file:        do_gaussian.m
 % author:      Noemie Phulpin
 % description: gaussian scale space of image I
 %%

if(nargin<7) 
   sigma0=1.6*k;
end

if omin<0
   for o=1:-omin
	I=doubleSize(I);
   end
elseif omin>0
   for o=1:-omin
	I=halveSize(I);
   end
end
[M,N] = size(I);                      %size of image

k = 2^(1/S);                          %scale space multiplicative step k
sigma0=1.6*k;                         %definition by Lowe
dsigma0 = sigma0*sqrt(1-1/k^2);       %scale step factor
sigmaN=0.5;                           %nominal smoothing of the image
so=-smin+1;                           %index offset

%scale space structure
L.O = O;
L.S = S;
L.sigma0 = sigma0;
L.omin = omin;
L.smin = smin;
L.smax = smax;


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%First Octave  
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%initilize the octave with S sub-levels
L.octave{1} = zeros(M,N,smax-smin+1); 

%initilize the first sub-level
sig=sqrt( (sigma0*k^smin)^2 - (sigmaN/2^omin)^2 );
%b=smooth2(I,sig) ;
%[N1,M1]=size(b)
%b(1:4,1:4)
%c=imsmooth(I,sig) ;
%[N2,M2]=size(c)
%c(1:4,1:4)
L.octave{1}(:,:,1) = smooth(I,sig);

%other sub-levels 
for s=smin+1:smax
    dsigma = k^s * dsigma0;
    L.octave{1}(:,:,s+so) = smooth( squeeze(L.octave{1}(:,:,s-1+so)) ,dsigma);
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Folowing Octaves
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%convert all octaves
for o=2:O
    
    sbest = min(smin+S,smax);
    TMP = halvesize( squeeze(L.octave{o-1}(:,:,sbest+so)) );
    sigma_next = sigma0*k^smin;
    sigma_prev = sigma0*k^(sbest-S);
    
    if (sigma_next>sigma_prev)
       sig=sqrt(sigma_next^2-sigma_prev^2);
       TMP= smooth( TMP,sig);
    end
    
    [M,N] = size(TMP);
    L.octave{o} = zeros(M,N,smax-smin+1); 
    L.octave{o}(:,:,1) = TMP;
    
    %other sub-levels 
    for s=smin+1:smax
        dsigma = k^s * dsigma0;
        L.octave{o}(:,:,s+so) = smooth( squeeze(L.octave{o}(:,:,s-1+so)) ,dsigma);
    end

end




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Auxiliary functions

function J = halvesize(I)
J=I(1:2:end,1:2:end);

function J = doubleSize(I)
[M,N]=size(I) ;
J = zeros(2*M,2*N) ;
J(1:2:end,1:2:end) = I ;
J(2:2:end-1,2:2:end-1) = ...
	0.25*I(1:end-1,1:end-1) + ...
	0.25*I(2:end,1:end-1) + ...
	0.25*I(1:end-1,2:end) + ...
	0.25*I(2:end,2:end) ;
J(2:2:end-1,1:2:end) = ...
	0.5*I(1:end-1,:) + ...
    0.5*I(2:end,:) ;
J(1:2:end,2:2:end-1) = ...
	0.5*I(:,1:end-1) + ...
    0.5*I(:,2:end) ;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
接下来开始 Differential scale space construction
function D = do_diffofg(L)

%% file:        do_diffofg.m
 % author:      Noemie Phulpin
 % description: substraction of consecutive levels of the scale space SS.
 %%


D.smin = L.smin;
D.smax = L.smax-1;
D.omin =L.omin;
D.O = L.O;
D.S = L.S;
D.sigma0 = L.sigma0;

for o=1:D.O
    
    [M,N,S] = size(L.octave{o});
    D.octave{o} = zeros(M,N,S-1);
    
    for s=1:S-1
        D.octave{o}(:,:,s) = L.octave{o}(:,:,s+1) -  L.octave{o}(:,:,s);   
    end;
    
end;

第三步:多组(octave)尺度空间的特征点检测计算

fprintf('CS5240 -- SIFT: computing octave %d\n', o-1+omin) ;
                tic ;


 % Local maxima of the DOG octave
    oframes1 = do_localmax(  difofg.octave{o}, 0.8*thresh, difofg.smin  ) ;
	oframes = [oframes1 , do_localmax( - difofg.octave{o}, 0.8*thresh, difofg.smin)] ; 
    
    
    fprintf('CS5240 -- SIFT: initial keypoints # %d.  \n', ...
      size(oframes, 2)) ;
    fprintf('                Time (%.3f s)\n', ...
       toc) ;
    tic ;
	
    if size(oframes, 2) == 0
        continue;
    end

 % Remove points too close to the boundary
    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) ;
		
	fprintf('CS5240 -- SIFT: keypoints # %d after discarding from boundary\n', size(oframes,2)) ;

 % Refine the location, threshold strength and remove points on edges
   	oframes = do_extrefine(...
 		oframes, ...
 		difofg.octave{o}, ...
 		difofg.smin, ...
 		thresh, ...
 		r) ;
   
   	fprintf('CS5240 -- SIFT: keypoints # %d after discarding from low constrast and edges\n',size(oframes,2)) ;
    fprintf('                Time (%.3f s)\n',  toc) ;
    tic ;
  
    fprintf('CS5240 -- SIFT: compute orientations of keypoints\n');

  % Compute the orientations
	oframes = do_orientation(...
		oframes, ...
		scalespace.octave{o}, ...
		scalespace.S, ...
		scalespace.smin, ...
		scalespace.sigma0 ) ;
	fprintf('                time: (%.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: keypoints # %d after orientation computation \n', size(frames,2)) ;

 % Descriptors
	
    fprintf('CS5240 -- SIFT: compute descriptors...\n') ;
    tic ;
		
	sh = do_descriptor(scalespace.octave{o}, ...
                    oframes, ...
                    scalespace.sigma0, ...
                    scalespace.S, ...
                    scalespace.smin, ...
                    'Magnif', magnif, ...
                    'NumSpatialBins', NBP, ...
                    'NumOrientBins', NBO) ;
    
    descriptors = [descriptors, sh] ;
    
    fprintf('                time: (%.3f s)\n\n\n',toc) ; 






    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值