本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权

欢迎关注我的博客:http://blog.csdn.net/hit2015spring和http://www.cnblogs.com/xujianqing/

这个系列的第三篇博客了,比以往时候来的更晚一些,期间经历了好多事,所以耽搁了分享的进程。Ok回到之前的sift算法的解读中来,这一篇博客主要是对sift算法的第三个步骤进行解读和分析,并给出matlab的代码注释,如有疏漏之处,欢迎指出交流!

上面一篇的博客我们讲到了提取出关键点了,这些关键点这时候是具有以下的特性的:尺度和位置的不变性,此时还缺少角度的不变性,这个步骤便是寻找这些关键点的角度的不变性。而后续的操作基本上都是基于这个角度进行的。

在图像中一个像素点往往是不具有说服力的,同样的一个特征点像素值它也不能代表着具有统计意义的图像特性。所以它的角度确定同样需要统计它周围的像素的一些特征,从而得到我们所需要的角度。每个特征点它有自己所在的高斯图像,也拥有自己的尺度信息,为了关联这些的特性,我们统计的是以该特征点为圆心,以该特征点所在的高斯图像的尺度的1.5倍为半径,该圆内所有的像素作为该特征点的角度的统计支持者。

像素梯度的幅值和幅角的计算公式为:

由此可以得到每一个点的幅值和幅角,但是由于与特征点的距离不同,各个点对特征点的支持也是不一样的,所以离得远的就支持弱一点,离得近的就支持大一点,这里面的权重就要通过一个规则来管理,而这个规则就是高斯滤波,即以特征点为圆心,做一个高斯滤波,给它周围的点加上一个高斯权重。高斯函数的方差当然还是与这个特征点所在的图像层的尺度有关,就是

计算完各个像素的幅值和幅角,并对幅值进行加权之后,我们要开始计算每一个像素对中心特征点的支持有多大。首先把一个圆周 分成36个柱体,每个柱体代表 ,表示的是 为第一个柱体, 为第二个柱体,依次类推下去,分成36个柱体。分好柱体之后开始统计工作。具体实行如下:

所有相关的像素点计算出来的幅角对应到各自的柱体中,如一个幅角为 ,则该点对应的柱体为 所代表的的柱体中,对各个柱体中的像素点的幅度进行加权求和,就可得到该特征点角度的分布直方图。

得到了特征点角度的分布直方图,当然是用得到分数最高的那个柱体所代表的的角度来表示该特征点的主方向。有时候一个特征点的角度可能会有好几个角度与峰值相差是比较少的,这样我们就可以用多个角度来辅助说明特征点的角度。我们把这个角度的差值定义为80%,只要大于最大峰值的80%就定为该特征点的辅助方向。

以上便是sift算法第三步的基本过程,这里面还差最后一部分的内容:为了对主方向上的角度进行精确地定位,我们需要根据其左右两个直方图进行插值处理,可以提高角度的精确程度。对于插值有各种各样的算法(数值分析这门课里面介绍了好多,请自行解决),在这里我用的是抛物线插值的方法对角度进行拟合。

抛物线插值:

给定三点 ,求线性Lagrange插值多项式 使得

于是可以得到下式的拟合

Ok,第三步骤完毕!这个步骤完后就可以得到特征点的主方向了。

下面是这一部分的matlab代码:

% 下一步是计算特征点的主方向.
% 在特征点的一个区域内计算其梯度直方图
g = gaussian_filter( 1.5 * absolute_sigma(1,intervals+3) / subsample(1) );
zero_pad = ceil( length(g) / 2 );% 计算高斯金字塔图像的梯度方向和幅值
if interactive >= 1
fprintf( 2, 'Computing gradient magnitude and orientation...\n' );
end
tic;
mag_thresh = zeros(size(gauss_pyr));
mag_pyr = cell(size(gauss_pyr));
grad_pyr = cell(size(gauss_pyr));
for octave = 1:octaves
for interval = 2:(intervals+1)% 计算x,y的差分
diff_x = 0.5*(gauss_pyr{octave,interval}(2:(end-1),3:(end))-gauss_pyr{octave,interval}(2:(end-1),1:(end-2)));
diff_y = 0.5*(gauss_pyr{octave,interval}(3:(end),2:(end-1))-gauss_pyr{octave,interval}(1:(end-2),2:(end-1)));% 计算梯度幅值
mag = zeros(size(gauss_pyr{octave,interval}));
mag(2:(end-1),2:(end-1)) = sqrt( diff_x .^ 2 + diff_y .^ 2 );% 存储高斯金字塔梯度幅值
mag_pyr{octave,interval} = zeros(size(mag)+2*zero_pad);
mag_pyr{octave,interval}((zero_pad+1):(end-zero_pad),(zero_pad+1):(end-zero_pad)) = mag;% 计算梯度主方向
grad = zeros(size(gauss_pyr{octave,interval}));
grad(2:(end-1),2:(end-1)) = atan2( diff_y, diff_x );
grad(find(grad == pi)) = -pi;% 存储高斯金字塔梯度主方向
grad_pyr{octave,interval} = zeros(size(grad)+2*zero_pad);
grad_pyr{octave,interval}((zero_pad+1):(end-zero_pad),(zero_pad+1):(end-zero_pad)) = grad;
end
end
clear mag grad
grad_time = toc;
if interactive >= 1
fprintf( 2, 'Gradient calculation time %.2f seconds.\n', grad_time );
end% 下一步是确定特征点的主方向
% 方法:通过寻找每个关键点的子区域内梯度直方图的峰值(注:每个关键点的主方向可以有不止一个)% g = gaussian_filter( 1.5 * absolute_sigma(1,intervals+3) / subsample(1) );
% zero_pad = ceil( length(g) / 2 );
% 将灰度直方图分为36等分,每隔10度一份
num_bins = 36;
hist_step = 2*pi/num_bins;
hist_orient = [-pi:hist_step:(pi-hist_step)];% 初始化关键点的位置、方向和尺度信息
pos = [];
orient = [];
scale = [];% 给关键点确定主方向
if interactive >= 1
fprintf( 2, 'Assigining keypoint orientations...\n' );
end
tic;
for octave = 1:octaves
if interactive >= 1
fprintf( 2, '\tProcessing octave %d\n', octave );
end
for interval = 2:(intervals + 1)
if interactive >= 1
fprintf( 2, '\t\tProcessing interval %d ', interval );
end
keypoint_count = 0;% 构造高斯加权掩模
g = gaussian_filter( 1.5 * absolute_sigma(octave,interval)/subsample(octave) );
hf_sz = floor(length(g)/2);
g = g'*g;loc_pad = zeros(size(loc{octave,interval})+2*zero_pad);
loc_pad((zero_pad+1):(end-zero_pad),(zero_pad+1):(end-zero_pad)) = loc{octave,interval};[iy ix]=find(loc_pad==1);
for k = 1:length(iy)x = ix(k);
y = iy(k);
% % 对其值进行高斯平滑
wght = g.*mag_pyr{octave,interval}((y-hf_sz):(y+hf_sz),(x-hf_sz):(x+hf_sz));
grad_window = grad_pyr{octave,interval}((y-hf_sz):(y+hf_sz),(x-hf_sz):(x+hf_sz));
orient_hist=zeros(length(hist_orient),1);
for bin=1:length(hist_orient)diff = mod( grad_window - hist_orient(bin) + pi, 2*pi ) - pi;orient_hist(bin)=orient_hist(bin)+sum(sum(wght.*max(1 - abs(diff)/hist_step,0)));end% 运用非极大抑制法查找主方向直方图的峰值
peaks = orient_hist;
% rot_right = [ peaks(end); peaks(1:end-1) ];
% rot_left = [ peaks(2:end); peaks(1) ];
% peaks( find(peaks < rot_right) ) = 0;
% peaks( find(peaks < rot_left) ) = 0;% 提取最大峰值的值和其索引位置
[max_peak_val ipeak] = max(peaks);% 将大于等于最大峰值80% 的直方图的也确定为特征点的主方向
peak_val = max_peak_val;
while( peak_val > 0.8*max_peak_val )% 最高峰值最近的三个柱值通过抛物线插值精确得到
A = [];
b = [];
for j = -1:1
A = [A; (hist_orient(ipeak)+hist_step*j).^2 (hist_orient(ipeak)+hist_step*j) 1];bin = mod( ipeak + j + num_bins - 1, num_bins ) + 1;
b = [b; orient_hist(bin)];
end
c = pinv(A)*b;
max_orient = -c(2)/(2*c(1));
while( max_orient < -pi )
max_orient = max_orient + 2*pi;
end
while( max_orient >= pi )
max_orient = max_orient - 2*pi;
end% 存储关键点的位置、主方向和尺度信息
pos = [pos; [(x-zero_pad) (y-zero_pad)]*subsample(octave) ];
orient = [orient; max_orient];
scale = [scale; octave interval absolute_sigma(octave,interval)];
keypoint_count = keypoint_count + 1;% % % 峰值赋0,考察的是下一个峰值,即大于主峰值80%的统计图
peaks(ipeak) = 0;
[peak_val ipeak] = max(peaks);
end
end
if interactive >= 1
fprintf( 2, '(%d keypoints)\n', keypoint_count );
end
end
end
clear loc loc_pad
orient_time = toc;
if interactive >= 1
fprintf( 2, 'Orientation assignment time %.2f seconds.\n', orient_time );
end% 在交互模式下显示关键点的尺度和主方向信息
if interactive >= 2
fig = figure;
clf;
imshow(im);
hold on;
display_keypoints( pos, scale(:,3), orient, 'y' );
% resizeImageFig( fig, size(im), 2 );
fprintf( 2, 'Final keypoints with scale and orientation (2x scale).\nPress any key to continue.\n' );
pause;
close(fig);
end
function hh = display_keypoints( pos, scale, orient, varargin )% 功能:在原始图像上显示特征点
% 输入:
% pos – 特征点的位置矩阵.
% scale –特征点的尺度矩阵.
% orient –特征点的主方向向量.
% 输出:
% hh-返回向量的线句柄.hold on;alpha = 0.33;
beta = 0.33;
autoscale = 1.5;
plotarrows = 1;
sym = '';filled = 0;
ls = '-';
ms = '';
col = '';varin = nargin - 3;while (varin > 0) & isstr(varargin{varin}),vv = varargin{varin};if ~isempty(vv) & strcmp(lower(vv(1)),'f')filled = 1;nin = nin-1;else[l,c,m,msg] = colstyle(vv);if ~isempty(msg), error(sprintf('Unknown option "%s".',vv));endif ~isempty(l), ls = l; endif ~isempty(c), col = c; endif ~isempty(m), ms = m; plotarrows = 0; endif isequal(m,'.'), ms = ''; end % Don't plot '.'varin = varin-1;end
endif varin > 0autoscale = varargin{varin};
endx = pos(:,1);
y = pos(:,2);
u = scale.*cos(orient);
v = scale.*sin(orient);if prod(size(u))==1, u = u(ones(size(x))); end
if prod(size(v))==1, v = v(ones(size(u))); endif autoscale,u = u*autoscale; v = v*autoscale;
endax = newplot;
next = lower(get(ax,'NextPlot'));
hold_state = ishold;x = x(:).'; y = y(:).';
u = u(:).'; v = v(:).';
uu = [x;x+u;repmat(NaN,size(u))];
vv = [y;y+v;repmat(NaN,size(u))];h1 = plot(uu(:),vv(:),[col ls]);if plotarrows,hu = [x+u-alpha*(u+beta*(v+eps));x+u; ...x+u-alpha*(u-beta*(v+eps));repmat(NaN,size(u))];hv = [y+v-alpha*(v-beta*(u+eps));y+v; ...y+v-alpha*(v+beta*(u+eps));repmat(NaN,size(v))];hold onh2 = plot(hu(:),hv(:),[col ls]);
elseh2 = [];
endif ~isempty(ms), hu = x; hv = y;hold onh3 = plot(hu(:),hv(:),[col ms]);if filled, set(h3,'markerfacecolor',get(h1,'color')); end
elseh3 = [];
endif ~hold_state, hold off, view(2); set(ax,'NextPlot',next); endif nargout>0, hh = [h1;h2;h3]; end

得到结果:

SIFT四部曲之——方向角度确定相关推荐

  1. SIFT四部曲之——高斯滤波

    版权声明:本文为博主原创文章,未经博主允许不得转载.博客不用于商业活动,博主对博客的使用,拥有最终解释权  本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权  欢 ...

  2. SIFT四部曲之——构建关键点特征描述符

    最近没空写最后一部分的内容,先把代码放上来 % SIFT 算法的最后一步是特征向量生成orient_bin_spacing = pi/4; orient_angles = [-pi:orient_bi ...

  3. SIFT四部曲之——极值检测和定位

    版权声明:本文为博主原创文章,未经博主允许不得转载.博客不用于商业活动,博主对博客的使用,拥有最终解释权 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关 ...

  4. python绝对方向角度值_哪个选项是turtle绘图中角度坐标系的绝对0度方向?_学小易找答案...

    [判断题]Internet是网络营销产生的概念基础. [单选题]哪个选项是turtle绘图中角度坐标系的绝对0度方向? [多选题]图中力 F 沿直角坐标轴方向 正交分解 , 在( )轴方向有分力. [ ...

  5. python绝对方向角度值_哪个选项是turtle绘图中角度坐标系的绝对0度方向?

    [单选题]哪个选项是程序的三种基本结构? [简答题]定义一个函数,实现如下功能: 获得用户输入数字N,计算并输出从N开始的5个质数,单行输出,质数间用逗号,分割. [其它]一个整数,它加上100后是一 ...

  6. DNF游戏中判断怪物相对于玩家的方向(角度)

    如果人物的X坐标大于怪物的X坐标,并且两个Y坐标相同,那怪物就在玩家的左边,其他的方向也是这样以此类推,这里就不贴代码了. 用数学公式先计算直线的斜率,然后计算弧度值,奈何博主(文盲)在百度一通后参考 ...

  7. ps如何重复复制一个相同的图层,以等距离、方向、角度复制?

    ps如何重复复制一个相同的图层,以等距离.方向.角度复制? 看着好看想要做,那就抓紧收藏起来. 先把想要进行重复的图层复制一个,然后Ctrl+T自由变换,设置好你想要的距离\方向\角度, 回车确认变换 ...

  8. Python计算机视觉——SIFT特征

    Python计算机视觉--SIFT特征 文章目录 Python计算机视觉--SIFT特征 写在前面 1 SIFT特征算法步骤 1.1 尺度空间的极值检测 1.2 特征点定位 1.3 特征方向赋值 1. ...

  9. SLAM前端 ---------特征提取之ORB(ORB与SIFT与SURF)

    ORB 论文翻译: 一种特征匹配替代方法:对比SIFT或SURF 1.ORB特征简介  ORB是Oriented FAST and Rotated BRIEF(oFAST and rBRIEF)的简称 ...

  10. 详解计算机视觉中的特征点检测:Harris / SIFT / SURF / ORB

    作者丨Encoder@知乎 来源丨https://zhuanlan.zhihu.com/p/36382429 编辑丨极市平台 本文仅用于学术分享,若侵权,联系后台作删文处理.极市导读 Harris角点 ...

最新文章

  1. jQuery对象和DOM对象使用说明
  2. oracle:instance与database,启动过程
  3. SpringMVC学习(一)——快速搭建SpringMVC开发环境(非注解方式)
  4. win10电脑开机密码忘了怎么办_电脑开机密码忘了怎么办最简单的方法_windows7教程...
  5. linux 停用用户,linux – 如何禁用用户的网络访问?
  6. unity直播推流方式_【技术猩球】从方案架构分析秀场直播的四种实现方式
  7. 时间java_Java 日期时间
  8. 湖南联通云计算与IDC掀发展浪潮
  9. matlab做信号完整性,关于Matlab的Turbo码仿真研究
  10. mysql explain 类似_Oracle有没有类似MySQL中的explain功能
  11. python3.7-secrets模块
  12. 华为通用软件开发面试(一二+主管面)
  13. 云计算平台技术及应用
  14. JavaScript 简单学习
  15. 哈工大数据库系统(上):嵌入式SQL语言之动态SQL(十)课后测验与作业
  16. C语言例题——输入两个正整数m和n,求其最大公约数和最小公倍数。
  17. e语言mysql怎么放在超级列表框_易语言如何把从mssql数据库读出来的信息全部显示在超级列表框内...
  18. 【第108期】技术大牛都在看的10本书,找到了
  19. 中国精细化工行业发展模式与十四五投资战略规划研究报告2022-2028年
  20. android sd卡数据恢复软件下载,sd卡数据恢复软件下载

热门文章

  1. Ctrl+Shift+F 输入法变成繁体 输入法简体繁体切换
  2. 计算机所占比例的函数,(excel求百分比函数公式)excel所占比例怎么算
  3. 摄影基础知识——白平衡
  4. MEM-英语 : 单词速记整理
  5. css样式给标签加上小手图标
  6. PROFINET通信基础知识
  7. 程序员必备开发神器【MAC篇】
  8. Bitset 源码解析
  9. linux tomcat apr安装,Linux下为Tomcat安装APR
  10. 【二十六】redis之事务、事务特性、与pipeline比较,与Lua脚本比较