www.pudn.com > MatlabSIFTcode_1.rar > find_features.m


 
%///////////////////////////////////////////////////////////////////////////////////////////// 
% 
% find_features - scale space feature detector based upon difference of gaussian filters. 
%                 selects features based upon their maximum response in scale space 
% 
% Usage:  maxima = find_features(pyr, img, thresh, radius, radius2, min_sep, edgeratio, disp_flag, img_flag) 
% 
% Parameters:   
%            pyr :      cell array of filtered image pyramid (built with build_pyramid) 
%            img :      original image (only used for visualization) 
%            thresh :   threshold value for maxima search (minimum filter response considered) 
%            radius :   radius for maxima comparison within current scale 
%            radius2:   radius for maxima comparison between neighboring scales 
%            disp_flag: 1- display each scale level on separate figure.  0 - display nothing 
%            img_flag: 1 - display filter responses. 0 - display original images. 
% 
% Returns: 
% 
%            maxima  - cell array of nX2 matrices of row,column coordinates of selected points on each scale level 
% 
% Author:  
% Scott Ettinger 
% scott.m.ettinger@intel.com 
% 
% May 2002 
%///////////////////////////////////////////////////////////////////////////////////////////// 
 
function maxima = find_features(pyr, img, scl, thresh, radius, radius2, disp_flag, img_flag) 
  %                pts = find_features(pyr,img,scl,thresh,radius,radius2,disp_flag,1); 
 
 
levels = size(pyr); 
levels = levels(2); 
 
mcolor = [ 0 1 0;   %color array for display of features at different scales 
           0 1 0; 
           1 0 0; 
           .2 .5 0; 
           0 0 1; 
           1 0 1; 
           0 1 1; 
           1 .5 0 
           .5 1 0 
          0 1 .5 
           .5 1 .5]; 
 
 
[himg,wimg] = size(img);                                            %get size of images 
[h,w] = size(pyr{2}); 
 
     
for i=2:levels-1 
 
    [h,w] = size(pyr{i}); 
    [h2,w2] = size(pyr{i+1}); 
     
    %find maxima 
    mx = find_extrema(pyr{i},thresh,radius);                        %find maxima at current scale level 
    mx2 = round((mx-1)/scl) + 1;                                    %find coords in level above         
    mx_above = neighbor_max(pyr{i},pyr{i+1},mx,mx2,radius2);        %do neighbor comparison in scale space above 
 
    if i>1 
        mx2 = round((mx-1)*scl) + 1;                                %find coords in level below      
        mx_below = neighbor_max(pyr{i},pyr{i-1},mx,mx2,radius2);    %do comparison in scale below 
     
        maxima{i} = plist(mx, mx_below & mx_above);                 %get coord list for retained maxima and minima 
    else 
        maxima{i} = plist(mx, mx_above); 
    end 
        
    %find minima 
    %if i==11, 
    %    keyboard; 
    %end; 
     
    mx = find_extrema(-pyr{i},thresh,radius);                       %find minima at current scale level 
    mx2 = round((mx-1)/scl) + 1;                                    %find coords in level above         
    mx_above = neighbor_max(-pyr{i},-pyr{i+1},mx,mx2,radius2);      %do neighbor comparison in scale space above 
    if i>1 
        mx2 = round((mx-1)*scl) + 1;                                %find coords in level below      
        mx_below = neighbor_max(-pyr{i},-pyr{i-1},mx,mx2,radius2);  %do comparison in scale below 
     
        mxtemp = plist(mx, mx_below & mx_above);                    %get coord list for retained maxima and minima 
    else 
        mxtemp = plist(mx, mx_above); 
    end 
   
 
    maxima{i} = [maxima{i}; mxtemp];                                %combine maxima and minima into list for return 
     
     
    %display results if desired 
    if disp_flag > 0                                                 
        figure 
        if img_flag == 0 
            tmp=resample_bilinear(img,himg/h); 
            imagesc(tmp); 
            colormap gray; 
            show_plist(maxima{i},mcolor(mod(i-1,7)+1,:),'+'); 
        else 
            imagesc(pyr{i}); 
            colormap gray; 
            show_plist(maxima{i},mcolor(mod(i-1,7)+1,:),'+'); 
        end 
    end     
end 
     
%////////////////////////////////////////////////////////////////////////////////////////////// 
% 
%   Compare a vector of pixels with its neighbors in another scale  
% 
%////////////////////////////////////////////////////////////////////////////////////////////// 
 
function v = neighbor_max(img1,img2,i,i2,radius)                    % i and i2 are column vectors of r,c coords 
     
    if (size(i2,1))==0 | size(img2,1)<11 | size(img2,2)<11 
        v=zeros(length(i),1); 
    else 
         
        [h,w] = size(img1); 
        [h2,w2] = size(img2); 
     
        [y,x]=meshgrid(-20:20,-20:20);                              %create set of offsets within radius  
        z = (x.^2+y.^2)<=radius^2; 
        [y,x]=find(z); 
        x=x-21; y=y-21; 
     
        radius=ceil(radius); 
     
        bound = ones(size(i2,1),2)*[h2-radius 0;0 w2-radius];        %create boundary listing 
        i2 = i2 - ((i2 > bound).*(i2-bound+1));                      %test bounds to make all points within image 
        i2 = i2 + ((i2 < radius+1).*(radius-i2+1)); 
         
         
        i2 = vec(i2,h2);                                             %create indices from x,y coords 
        i = vec(i,h); 
     
        p = img1(i); 
        res = ones(length(i),1); 
     
        for j=1:length(x)                                            %check against all points within radius 
            itest = i2 + x(j) + h2*y(j); 
            p2 = img2(itest); 
            res = res & (p>=p2); 
        end 
 
         
        v = res;                                                     %store results in binary vector 
    end 
     
%////////////////////////////////////////////////////////////////////////////////////////////// 
 
function v = vec(points,h) 
 
    y = points(:,1); 
    x = points(:,2); 
     
    v = y + (x-1)*h;  %create index vectors 
     
%////////////////////////////////////////////////////////////////////////////////////////////// 
 
function p = plist(points, flags) 
 
    p = points(find(flags),:);