将多尺度SIFT改为单尺度上应用

在网上看到好多Harris-SIFT特征提取的文章,可惜找不到程序,因此本人痛下决心,决定自己改写一份。

我们都知道,SIFT是在多尺度上提取特征点,生成特征描述子,然后再匹配。

在多尺度上提取的一个特征点有三个信息:分别是位置信息、尺度信息、方向信息;

将SIFT改在单尺度上应用,提取的特征点就只能包含位置信息和方向信息了,然后通过这两个信息来生成特征描述子。

一般情况下,我们可以根据自己需要的算法提取出特征点,这时候后提取的特征点仅仅拥有位置信息,如果利用区域灰度匹配的话,我们通常会以特征点为中心选择一块区域去做匹配。现在我们在单尺度上改为应用SIFT中生成特征描述子的方法来匹配。

首先,根据我们自己的算法提取出想要的特征点以后,特征点具有位置信息,下来我们该对特征点赋予方向信息:本人依据多尺度SIFT自己改写的在单尺度下的特征点赋予主方向的程序为:

frames=MajorOrientation(mag,ang,x,y)

其中x,y 为我们提取特征的位置坐标,mag,ang为以位置坐标为中心的某领域的方向和角度矩阵,在调用MajorOrientation前首先的求出来;

求mag和ang的程序如下:其中img为包含特征点的图片


function [mag,ang]=MagAndAng(img) 
%input:
 % img:input image;
%output:
 % mag: the magnitudes;
 % ang: the angles;
 
%the fucniton is to calculate the magintudes and angles and save it in mag
%and ang;
%step 1:compute x and y derivates using pixel difference;
% %compute x and y derivates using pixel difference;
% diff_x = 0.5*(img(2:(end-1),3:(end))-img(2:(end-1),1:(end-2)));
% diff_y = 0.5*(img(3:(end),2:(end-1))-img(1:(end-2),2:(end-1)));
dx_filter = [-0.5 0 0.5];
dy_filter = dx_filter';
gradient_x = imfilter(img, dx_filter);
gradient_y = imfilter(img, dy_filter);
gradient_x=double(gradient_x);
gradient_y=double(gradient_y);
% %compute the magnitude of the gradient;
magnitudes=sqrt(gradient_x.^2+gradient_y.^2);


% %compute the orientation of the gradient;
% angles=atan2( gradient_x, gradient_y );
angles=mod(atan(gradient_y ./ (eps + gradient_x)) + 2*pi, 2*pi);
% angles(find(angles == pi)) = -pi;
% Store the magnitude of the gradient and the orientation of the gradient
% mag=magnitudes(2:end-1,2:end-1);
% ang=angles(2:end-1,2:end-1);
mag=magnitudes;
ang=angles;


end

根据mag和ang计算主方向的程序如下:

function frames=MajorOrientation(mag,ang,x,y)
% The next step of the algorithm is to assign orientations to the keypoints
% that have been located.  This is done by looking for peaks in histograms of
% gradient orientations in regions surrounding each keypoint.  A keypoint may be 
% assigned more than one orientation.  If it is, then two identical descriptors 
% are added to the database with different orientations.
%input:
 %mag:幅度
 %ang:角度
 %x;特征点x坐标
 %y:特征点y坐标
%output:
 %frames:位置信息及主方向和若干个从方向信息;                
win_factor = 1.5 ;  
NBINS = 36;                   %直方图36柱
histo = zeros(1, NBINS);      %初始化直方图数组
sigmaw = win_factor *6.4 ;  %高斯加权因子
W = floor(3.0* 1.5*6.4);                              %高斯加权窗口直径 
[M, N] = size(mag); % M 是图像的高度, N 是图像的宽度; num_level 是该组尺度空间的层数


xp=x;
yp=y;
magnitudes=mag;
angles=ang;


for xs = xp - max(W, xp-1): min((N - 2), xp + W)
     for ys = yp - max(W, yp-1) : min((M-2), yp + W)
            dx = (xs - x);
            dy = (ys - y);
            if dx^2 + dy^2 <= W^2 % 点在高斯加权圆内
               wincoef = exp(-(dx^2 + dy^2)/(2*sigmaw^2));
               bin = round( NBINS *  angles(ys, xs)/(2*pi) + 0.5); %最近取整,确定所在方向直方图的柱


               histo(bin) = histo(bin) + wincoef * magnitudes(ys, xs); %用高斯加权后的向量幅度做直方图值累加
            end
            
     end
end
% figure(2);
% bar(histo);
frames=[];
theta_max = max(histo);   %找到直方图峰值
theta_indx = find(histo> 0.8 * theta_max); %关键点方向索引,大于80%峰值的角度
for i = 1: size(theta_indx, 2)
        theta = 2*pi * theta_indx(i) / NBINS;
        frames = [frames, [xp yp theta]'];        
end


end

通过函数MajorOrientation传出的参数frames 我们可以看到,frames包含每个特征点的位置信息xp,yp,还有包含主方向信息theta;

接下来我们就依据位置和主方向信息在单尺度上生成特征描述子,其程序如下:


function desc=DESC(frames,mag,angles)
nbp=4;
desc=zeros(1,nbp*nbp*8);


    o=1;
    s=1;
    [M,N]=size(mag);
    sigm0=3.2;
    sbp=3*sigm0;
    W=floor(sqrt(2)*sbp*(nbp+1)/2+0.5);
    xp=fix(frames(1,1));
    yp=fix(frames(2,1));
    theta0=frames(3,1);
    sin0=sin(theta0);
    cos0=cos(theta0);
    index=0;
    histo=zeros(1,nbp*nbp*8);
    for xs = xp - min(W, xp-1): min((M - 1), xp + W)
        for ys = yp - min(W, yp-1) : min((N-1), yp + W)
            dx=xp-xs;
            dy=yp-ys;
            if dx^2+dy^2<W^2
                theta=angles(xs,ys);
                theta=mod((theta-theta0),2*pi);
                nx=(dy*cos0+dx*sin0)/sbp;
                ny=(-dy*sin0+dx*cos0)/sbp;
                nt=theta/pi*4;
                wsigma = nbp/2;
                mags=mag(xs,ys);
                wc=exp(-(nx*nx + ny*ny)/(2.0 * wsigma * wsigma));
                for cx=-1.5:1:1.5
                    for cy=-1.5:1:1.5
                        
                        if abs(nx-cx)<1&&abs(ny-cy)<1
                            ki=cx+2.5;
                            kj=cy+2.5;
                            ni1=ceil(nt);
                            ni2=floor(nt);
                            d=(1-abs(nx-cx))*(1-abs(ny-cy));
                            index=(((ki-1)*nbp+kj)-1)*8;
                            if ni1~=ni2
                                
                                dt1=1-(ni1-nt);
                                dt2=1-(-ni2+nt);
                                index1=index+mod(ni1,8)+1;
                                index2=index+ni2+1;
                                histo(index1)=histo(index1)+wc*d*dt1*mags;
                                histo(index2)=histo(index2)+wc*d*dt2*mags;
                            else
                                histo(index+ni1+1)=histo(index+ni1+1)+wc*d*mags;
                            end
                        end
                    end
                end
            end
        end
    end
    desc=histo;
     
desc = desc ./ norm(desc);
indx = desc > 0.2;
desc(indx) = 0.2;
desc = desc ./ norm(desc);

通过函数DESC便可以求出一个特征点的特征描述子,可以看出最后对特征描述子进行了归一化,返回的desc为所求的128维特征描述子。

接下来我是利用harris角点检测算子检测特征点,然后和单尺度上的SIFT结合起来,进行的特征提取和匹配,结果如下图所示。




  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值