function [tg,theta] = tgmo2(tmap,ntex,radius,norient,varargin) % function [tg,theta] = tgmo2(tmap,ntex,radius,norient,...) % % Compute the texture gradient at a single scale and multiple % orientations. % % INPUT % tmap Texton map, values in [1,ntex]. % ntex Number of textons. % radius Radius of disc for texture gradient. % norient Number of orientation at which to compute % the texture gradient. % 'smooth' Smoothing method, one of % {'gaussian','savgol','none'}, default 'none'. % 'sigma' Sigma for smoothing, default to radius. % 'tsim' Texton similarity matrix. If not % provided, then use chi-squared. % % OUTPUT % tg Size [h w norient] array of tg images. % theta Vector of disc orientations (which are % orthogonal to the texture gradient). % % David R. Martin % March 2003 % process options smooth = 'none'; sigma = radius; usechi2 = true; for i = 1:2:numel(varargin), opt = varargin{i}; if ~ischar(opt), error('option names not a string'); end if i==numel(varargin), error(sprintf('option ''%s'' has no value',opt)); end val = varargin{i+1}; switch opt, case 'smooth', switch val, case {'none','gaussian','savgol'}, smooth=val; otherwise, error(sprintf('invalid option smooth=''%s''',val)); end case 'sigma', sigma=val; case 'tsim', tsim=val; usechi2=false; otherwise, error(sprintf('invalid option ''%s''',opt)); end end radius = max(1,radius); norient = max(1,norient); theta = (0:norient-1)/norient*pi; % check texton labels if any(tmap~=round(tmap)), error('texton labels not integral'); end if min(tmap(:)) < 1 | max(tmap(:))>ntex, error(sprintf('texton labels out of range [1,%d]',ntex)); end % radius of discrete disc wr = floor(radius); % count number of pixels in a disc [u,v] = meshgrid(-wr:wr,-wr:wr); gamma = mod(atan2(v,u),2*pi); mask = (u.^2 + v.^2 <= radius^2); mask(wr+1,wr+1) = 0; % mask out center pixel to remove bias count = sum(mask(:)); % determine which pie slice each pixel falls into % 0=masked [1,2*norient]=slice slice = 1 + floor(gamma/(pi/norient)); slice = slice .* mask; [h,w] = size(tmap); tg = zeros(h,w,norient); fwrite(2,'['); for x = 1:w, fwrite(2,'.'); for y = 1:h, pie = zeros(ntex,2*norient); for u = -wr:wr, xi = x + u; if xi<1 | xi>w, continue; end for v = -wr:wr, yi = y + v; if yi<1 | yi>h, continue; end s = slice(v+wr+1,u+wr+1); if s==0, continue; end % masked out t = tmap(yi,xi); pie(t,s) = pie(t,s) + 1; end end pie = pie .* (2/count); % normalize % initialize left/right histograms lhist = sum(pie(:,1:norient),2); rhist = sum(pie(:,norient+1:end),2); % spin the disc to compute tg at each orientation for i = 1:norient, if usechi2, chi = (lhist-rhist).^2 ./ (lhist+rhist+eps); tg(y,x,i) = 0.5*sum(chi); else lrdiff = abs(lhist-rhist); tg(y,x,i) = lrdiff' * tsim * lrdiff; end if i