www.gusucode.com > MATLAB实现图像的SIFT特征提取,并做在不同光照、不同视角下的特征匹配 > orientation/do_orientation.m
function oframes = do_orientation(oframes, octave, S, smin,sigma0 ) % this function computes the major orientation of the keypoint (oframes). % Note that there can be multiple major orientations. In that case, the % SIFT keys will be duplicated for each major orientation % Author: Yantao Zheng. Nov 2006. For Project of CS5240 frames = []; win_factor = 1.5 ; NBINS = 36; %直方图36柱 histo = zeros(1, NBINS); %初始化直方图数组 [M, N, s_num] = size(octave); % M 是图像的高度, N 是图像的宽度; num_level 是该组尺度空间的层数 key_num = size(oframes, 2); %关键点数目 magnitudes = zeros(M, N, s_num); %像素向量幅度数组 angles = zeros(M, N, s_num); %像素幅角数组 % compute image gradients 计算图像梯度 for si = 1: s_num img = octave(:,:,si); dx_filter = [-0.5 0 0.5]; dy_filter = dx_filter'; gradient_x = imfilter(img, dx_filter); gradient_y = imfilter(img, dy_filter); magnitudes(:,:,si) =sqrt( gradient_x.^2 + gradient_y.^2); angles(:,:,si) = mod(atan(gradient_y ./ (eps + gradient_x)) + 2*pi, 2*pi); end % round off the cooridnates and x = oframes(1,:); y = oframes(2,:) ; s = oframes(3,:); x_round = floor(oframes(1,:) + 0.5); y_round = floor(oframes(2,:) + 0.5); scales = floor(oframes(3,:) + 0.5) - smin; for p=1:key_num %对每个关键点进行处理 s = scales(p); xp= x_round(p); yp= y_round(p); sigmaw = win_factor * sigma0 * 2^(double (s / S)) ; %高斯加权因子 W = floor(3.0* sigmaw); %高斯加权窗口直径 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(p)); dy = (ys - y(p)); if dx^2 + dy^2 <= W^2 % 点在高斯加权圆内 wincoef = exp(-(dx^2 + dy^2)/(2*sigmaw^2)); bin = round( NBINS * angles(ys, xs, s+ 1)/(2*pi) + 0.5); %最近取整,确定所在方向直方图的柱 histo(bin) = histo(bin) + wincoef * magnitudes(ys, xs, s+ 1); %用高斯加权后的向量幅度做直方图值累加 end end end 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, [x(p) y(p) s theta]']; end end oframes = frames; % for each keypoint