⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sift.m

📁 The matlab source code about SIFT algorithm with Accurate Key locations.
💻 M
字号:
function [image,count,Keypoint,featureAll] = SIFT(imagefile)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%    
%   SIFT 算法测试程序 
%   identify the feature descriptors 
%                                          program by super xiaoweige
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
           % 12.1=(10+1)^2/10
           % 10 = (8+1)^2/8;
           % 7.2= (5+1)^2/5;
           % 4.5= (2+1)^2/2;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%image = imread('E:\MatlabWork\sift\scene.pgm');
image=imread(imagefile);
if isrgb(image)
    image = rgb2gray(image);
end
image = im2double(image);
[ix,iy] = size(image);
%检测可能的感兴趣点。即检测尺度空间中的关于尺度的极值点。即找出相邻高斯滤波后的极值点坐标和尺度(即sigma)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% double the input image using linear interpolation prior to building the first level of the pyramid 
%imageT = double(zeros(2*ix-1,2*iy-1));
%for i = 1:ix
%    for j = 1:iy
%        imageT(2*i-1,2*j-1) = image(i,j);
%    end
%end
%for i = 1:ix-1
%   for j = 1:iy
%        imageT(2*i,2*j-1) = (imageT(2*i-1,2*j-1)+imageT(2*i+1,2*j-1))/2;
%    end
%end
%for i = 1:2*ix-1
%    for j = 1:iy-1
%        imageT(i,2*j) = (imageT(i,2*j-1)+imageT(i,2*j+1))/2;
%    end
%end
imageT = image;
[sizeX,sizeY] = size(imageT);


imageT = imageT-min(imageT(:)); % transform the image to [0 1]
imageT = imageT/max(imageT(:));

FirstSigma = 0.8;
Gau = fspecial('gaussian',[9 9],FirstSigma);  %prior smoothing using sigma = 1.414
imageT=imfilter(imageT,Gau);      %与高斯模板做卷积

count = 0;
Keypoint = zeros(1,6);
featureAll= zeros(1,128);
RunNum = 0;%RunNum = -1;
ScaDoG = zeros(6,1);


while (sizeX>20 & sizeY>20) 

ix=sizeX
iy=sizeY
IMG = zeros(sizeX,sizeY,6);
DoG = zeros(sizeX,sizeY,5);  % DoG 

IMG(:,:,1) = imageT;
%gwid = max(5,fix(Sig));
ScaDoG(1) = FirstSigma*2^RunNum;
for i=1:1:5
    %Sigma = Sig+SigDiff*(i-3);    
    %GauWid = [2*gwid+1 2*gwid+1];  % 可变宽度的高斯滤波器 和不可变宽度的高斯滤波器. [2*i+1 2*i+1]
    Sigma = 2^(i/5);
    Gau = fspecial('gaussian',[9 9],Sigma);
    IG=imfilter(imageT,Gau);      %与高斯模板做卷积
    IMG(:,:,i+1) = IG;
    ScaDoG(i+1) = Sigma*ScaDoG(1);
end
clear Gau;
clear IG;
%DoG(:,:,1) = IMG(:,:,1) - imageT;  
for i = 1:1:5;
    DoG(:,:,i) = IMG(:,:,i+1)-IMG(:,:,i);    % DoG 
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% identify the keypoint
%L = DoG;
countT = 1;
countTT = 1;
for k = 3:4
   for i = 11:1:ix-10
       for j = 11:1:iy-10           
           %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
           D = DoG(i,j,k);
           DoGTemp = DoG(i-1:i+1,j-1:j+1,k);           
           if D == max(DoGTemp(:))
               DoGTemp1 = DoG(i-1:i+1,j-1:j+1,k-1);
               if D > max(DoGTemp1(:))
                   DoGTemp2 = DoG(i-1:i+1,j-1:j+1,k+1);
                   if D > max(DoGTemp2(:))
                       
                       countT = countT+1;
                       Dxx = DoG(i+1,j,k)+DoG(i-1,j,k)-2*DoG(i,j,k);
                       Dyy = DoG(i,j+1,k)+DoG(i,j-1,k)-2*DoG(i,j,k);
                       Dxy = DoG(i+1,j+1,k)+DoG(i,j,k)-DoG(i+1,j,k)-DoG(i,j+1,k);                       
                       r = (Dxx+Dyy)^2/(Dxx*Dyy-Dxy^2);
                       if r<12.1
                           countTT=countTT+1;
                           Dx = DoG(i+1,j,k)-DoG(i,j,k);
                           Dy = DoG(i,j+1,k)-DoG(i,j,k);
                           Dz = DoG(i,j,k+1)-DoG(i,j,k);
                           Dxz = DoG(i+1,j,k+1)+DoG(i,j,k)-DoG(i+1,j,k)-DoG(i,j,k+1);
                           Dyz = DoG(i,j+1,k+1)+DoG(i,j,k)-DoG(i,j+1,k)-DoG(i,j,k+1);
                           Dzz = DoG(i,j,k+1)+DoG(i,j,k-1)-2*DoG(i,j,k);
                           xhTemp = [Dxx Dxy Dxz;Dxy Dyy Dyz;Dxz Dyz Dzz];
                           xHead = inv(xhTemp)*[Dx Dy Dz]';
                           if abs(xHead(1))<1 & abs(xHead(2))<1 & abs(xHead(3))<0.5
                               DxHead = DoG(i,j,k) + 1/2*[Dx Dy Dz]*xHead;
                               %if abs(DxHead) >0.03
                                   count = count+1;
                                   key = [i+xHead(1),j+xHead(2),ScaDoG(k)+xHead(3),0,0,0];
                                   %key = [scaleX scaleY scale 0 0 0];
                                   [featureA,key] = descriptor(key,IMG(:,:,k),count,RunNum);
                                   Keypoint(count,:) = key;
                                   featureAll(count,:) = featureA;
                                   %end
                           end
                       end
                   end
               end               
           %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
           elseif D==min(DoGTemp(:))
               DoGTemp1 = DoG(i-1:i+1,j-1:j+1,k-1);
               if D < min(DoGTemp1(:))
                   DoGTemp2 = DoG(i-1:i+1,j-1:j+1,k+1);
                   if D < min(DoGTemp2(:)) 
                       countT = countT+1;
                       Dxx = DoG(i+1,j,k)+DoG(i-1,j,k)-2*DoG(i,j,k);
                       Dyy = DoG(i,j+1,k)+DoG(i,j-1,k)-2*DoG(i,j,k);
                       Dxy = DoG(i+1,j+1,k)+DoG(i,j,k)-DoG(i+1,j,k)-DoG(i,j+1,k);                       
                       r = (Dxx+Dyy)^2/(Dxx*Dyy-Dxy^2);
                       if r<12.1
                           countTT=countTT+1;
                           Dx = DoG(i+1,j,k)-DoG(i,j,k);
                           Dy = DoG(i,j+1,k)-DoG(i,j,k);
                           Dz = DoG(i,j,k+1)-DoG(i,j,k);
                           Dxz = DoG(i+1,j,k+1)+DoG(i,j,k)-DoG(i+1,j,k)-DoG(i,j,k+1);
                           Dyz = DoG(i,j+1,k+1)+DoG(i,j,k)-DoG(i,j+1,k)-DoG(i,j,k+1);
                           Dzz = DoG(i,j,k+1)+DoG(i,j,k-1)-2*DoG(i,j,k);
                           xhTemp = [Dxx Dxy Dxz;Dxy Dyy Dyz;Dxz Dyz Dzz];
                           xHead = inv(xhTemp)*[Dx Dy Dz]';
                           if abs(xHead(1))<1 & abs(xHead(2))<1 & abs(xHead(3))<0.5
                               DxHead = DoG(i,j,k) + 1/2*[Dx Dy Dz]*xHead;
                               %if abs(DxHead) >0.03
                                   count = count+1;
                                   key = [i+xHead(1),j+xHead(2),ScaDoG(k)+xHead(3),0,0,0];
                                   %key = [scaleX scaleY scale 0 0 0];
                                   [featureA,key] = descriptor(key,IMG(:,:,k),count,RunNum);
                                   Keypoint(count,:) = key;
                                   featureAll(count,:) = featureA;
                                   %end
                           end
                       end
                            
                   end
               end
           end
            
        end %for j
    end %for i
end % for k = 2:4  

countT
countTT
imageT = imageT(1:2:end,1:2:end);
[sizeX,sizeY] = size(imageT);

clear IMG;
clear DoG;
RunNum = RunNum +1;

end  % while(sizeX+sizeY)/2 > 

count








function [featureA,key] = descriptor(key,IM,icount,RunNum)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%for i = countPrevious+1:count
    x = fix(key(1));
    y = fix(key(2));
    %k = key(3);
    key(4) = sqrt((IM(x+1,y)-IM(x-1,y))^2+(IM(x,y+1)-IM(x,y-1))^2);
    key(6) = atan2(IM(x,y+1)-IM(x,y-1),IM(x+1,y)-IM(x-1,y));
        
    Orient = zeros(1,4);    % 先设置关键点只有四个方向,即只包含与坐标轴平行的方向。上下左右,先看看效果,再考虑8个以上方向
    for m = x-1:1:x+1
        for n = y-1:1:y+1
            theta = atan2(IM(m,n+1)-IM(m,n-1),IM(m+1,n)-IM(m-1,n));
            thetaT = fix((theta + pi)/(pi/4)); % 将-pi到 pi的theta 转化成代表其区间整数
            switch thetaT
                case {0,7}
                    Orient(1) = Orient(1)+1;
                case {1,2}
                    Orient(2) = Orient(2)+1;
                case {3,4}
                    Orient(3) = Orient(3)+1;
                case {5,6}
                    Orient(4) = Orient(4)+1;
                otherwise
                    %    4     
                    % 1     3
                    %    2
            end
        end
    end % for m = x-1:1:x+1
    [OriMax,OriI] = max(Orient);
    key(5) = OriI; %    
    %T(:,i) = Orient';
    
    key(1) = key(1)*(2^RunNum);  % must be checked later.
    key(2) = key(2)*(2^RunNum);    

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
    % feature descriptor & descriptor representation
    ori = key(5);
    igra = double(zeros(18,18));  % %因为需要16*16的特征矩阵来计算特征的128维表示.又因为需要计算每个点的梯度方向,所以,向各个方向放大一格
    % igra 只是将IM矩阵中特征点附近对应的数值按照特征点方向的要求复制出来.  矩阵的X 方向与特征点的梯度方向一致
    [sizeX,sizeY] = size(IM); 
    % 运算中先对图象的大小做了限定,不会有图片的宽度或长度少于20.   
    if x>=10 & x<=sizeX-8 & y>=10 & y<=sizeY-8
        igra = IM(x-9:x+8,y-9:y+8);        
    end
        %elseif x>=10 & x<=sizeX-8 & y>=10 & y>sizeY-8
        %igraT = IM(x-9:x+8,y-9:end);
        %igra(:,1:size(igraT,2)) = igraT;
        %elseif x>=10 & x<=sizeX-8 & y<10 & y<=sizeY-8
        
        
        
        switch ori
            case {1}                
                igra = rot90(igra,2);            
            case {2}
                rot90(igra);                
            case {3}       
            case {4}
                igra = rot90(igra,3);            
            otherwise            
        end % switch ori
    
        
    gra = double(zeros(16,16));
    graMag = double(zeros(16,16));
    
    DescriptorSig = 2;
    for m = 1:16
        for n = 1:16
            graMag(m,n) = sqrt((igra(m+2,n+1)-igra(m,n+1))^2+(igra(m+1,n+2)-igra(m+1,n))^2);%*(1/(2*pi*DescriptorSig^2)*exp(-((m-8.5)^2 + (n-8.5)^2)/(2*DescriptorSig^2)));
            gra(m,n) = atan2(igra(m+1,n+2)-igra(m+1,n),igra(m+2,n+1)-igra(m,n+1));
        end
    end    
    %featureA = double(zeros(1,128));
    for m = 1:4
        for n = 1:4
            feaOri8 = double(zeros(1,8));
            for p = (m-1)*4+1:(m-1)*4+4
                for q = (n-1)*4+1:(n-1)*4+4
                    feaOriT = fix((gra(p,q)+pi)/(pi/8));
                    switch feaOriT 
                        case {0,15}
                            feaOri8(1) = feaOri8(1) + graMag(p,q);
                        case {1,2}
                            feaOri8(2) = feaOri8(2) + graMag(p,q);
                        case {3,4}
                            feaOri8(3) = feaOri8(3) + graMag(p,q);
                        case {5,6}
                            feaOri8(4) = feaOri8(4) + graMag(p,q);
                        case {7,8}
                            feaOri8(5) = feaOri8(5) + graMag(p,q);
                        case {9,10}
                            feaOri8(6) = feaOri8(6) + graMag(p,q);
                        case {11,12}
                            feaOri8(7) = feaOri8(7) + graMag(p,q);
                        case {13,14}
                            feaOri8(8) = feaOri8(8) + graMag(p,q);
                        otherwise
                    end
                end
            end  % for p = (m-1)*4+1:(m-1)*4+4
            feaOriAll(:,(m-1)*4+n) = feaOri8';             
        end
    end %for m = 1:4    
    featureA = feaOriAll;
    featureA = reshape(featureA,1,128);
    if sum(featureA.^2) > 0
        featureA = featureA / sqrt(sum(featureA.^2));  % 特征归一化
    end
        %featureAll(icount,:) = featureA; 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -