GEOSUPERPIX_BASE - Base function for GEOSUPERPIX.
Contents
Syntax
[Q, LabCk, Ck] = geosuperpix_base(I, K, T, n, k, maxiter, method, ... rho, sigma, a, der, int, samp, eign);
See also
Ressembles: GEOSUPERPIX, AMOEBASUPERPIX_BASE, SLICSUPERPIX_BASE. Requires: RGB2LAB, IM2POTENTIAL, POTENTIAL2FRONT, GSTDECOMP.
Function implementation
%-------------------------------------------------------------------------- function [Q, Ck, LabCk] = ... geosuperpix_base(I, K, T, n, k, maxiter, method, ... rho, sigma, a, der, int, samp, eign)
% compute the set of gradient minima and their influence zone % select seeds on an uniform grid % for iteration % compute the distance to the seeds % end % we accept a variable number of inputs if nargin<14, eign = 'l1'; if nargin<13, samp = 1; if nargin<12, int = 'fast'; if nargin<11, der = 'fast'; if nargin<10, a = [1 2]; if nargin<9, sigma = 1; if nargin<8, rho = 1; if nargin7, method = 'ani'; if nargin<6, maxiter = Inf; if nargin<5, k = 3; end end end end end end end end end end [X,Y,C] = size(I); if C~=3 warning('geosuperpix_base:inputwarning','RGB image required in input'); if C==1, I = repmat(I, [1 1 3]); else I = I(:,:,1:3); end end
distance
distL2 = @(v0, v1) sqrt(sum((v1-v0).^2, 2));
for an image with N=X*Y pixels, the approximate size of each superpixel is N/K pixels; therefore, for roughly equally sized superpixels there would be a superpixel center at every grid interval S:
S = floor(sqrt(X*Y/K)); if mod(n,2)~=0, n = n+1; end; win = S*n; pad = win / 2; Lab = RGB2Lab(I(:,:,1), I(:,:,2), I(:,:,3)); A = padarray(Lab, [pad pad 0], 'both', 'replicate'); [M,N] = size(A(:,:,1));
we begin by sampling K regularly spaced cluster centers
[Ck, LabCk] = initcenters(I, K); nk = length(Ck); % % and we move the centers to seed locations corresponding to the lowest % % gradient position in a [k x k] neighborhood. % if k>0 % [Ck, LabCk] = movecenters(distL2, Lab, Ck, k, S, m); % end
compute once for all the potential function based on the gradient and/or the gradient structure tensor of the multispectral input image and define the propagation function: it is either a scalar field (isotropic case) providing with the speed (strenght) for the propagation (the higher the value at one point, the faster the propagation through this point) or a tensor field (anisotropic case) providing with a speed and a direction for the propagation.
[TT, L] = im2potential(A, method, a, rho, sigma, der, int, samp, eign); %#ok [~, L2, E1, E2] = gstdecomp(TT); %A = padarray(Lab, [pad pad 0], 'both', 'replicate'); %[M,N] = size(A(:,:,1)); Q = zeros(X,Y); D = Inf(M,N); % D = D(:); % indexes pixindex = reshape(1:M*N,M,N); pixin = pixindex(pad+1:pad+X,pad+1:pad+Y); % Index of the centered neighbour window of analysis ind = repmat(-pad:pad,[2*pad+1 1]); [x,y] = size(ind); ind = ind' + M*ind; ind = ind(:); % start looping niter = 1; err = Inf(nk,1); while niter<=maxiter ierr = find(err>T); if isempty(ierr), break; end Q = padarray(Q, [pad pad], 'both', 'replicate'); for k=1:nk %length(ierr) kk = k; c = pixin(Ck(kk,1),Ck(kk,2)); c3 = [c, c+N*M, c+2*N*M]; cind = c + ind; cind2 = repmat(c3(1:2),[x*y 1]) + repmat(ind,[1 2]); cind3 = repmat(c3,[x*y 1]) + repmat(ind,[1 3]); q = Q(cind); d = D(cind); l2 = reshape(L2(cind), [x y]); % l1 = reshape(L1(cind), [x y]); e2 = reshape(E2(cind2), [x y 2]); e1 = reshape(E1(cind2), [x y 2]); % a = reshape(distL2(A(cind3), squeeze(repmat(LabCk(k,:),[x*y 1]))), [x y]); a = reshape(distL2(A(cind3), repmat(LabCk(k,:),[x*y 1])), [x y]); % no, should average value l1 = 1 ./ (1+a); l2 = l2 ./ (1+a); ss = gstdecomp(l1, l2, e1, e2); dd = potential2front(ss, [pad+1;pad+1]); [d, r] = min(cat(2,d(:),dd(:)), [], 2); q(r==2) = k; Q(cind) = q; D(cind) = d; end Q = Q(pad+1:pad+X,pad+1:pad+Y); [nCk, nLabCk] = updatecenters(ierr, Q, Lab); warning('geosuperpix_base:warning','!!!update error vector!!!'); Ck(ierr,:) = nCk; LabCk(ierr,:) = nLabCk; niter = niter + 1; end
end % end of geosuperpix_base
Subfunction
%-------------------------------------------------------------------------- function [Ck, LabCk] = initcenters(Lab, S) [X,Y] = size(Lab(:,:,1)); xk = round(X / S); if xk==0, xk = floor(X/2); else xk = floor(S * (0:xk-1) + S/2); end yk = round(Y / S); if yk==0, yk = floor(X/2); else yk = floor(S * (0:yk-1) + S/2); end LabCk = reshape(Lab(xk,yk,:), [length(xk)*length(yk) 3]); [xk yk] = meshgrid(xk, yk); Ck = [xk(:), yk(:)]; % Ck = sub2ind([X,Y], xk(:), yk(:)); end % %---------------------------------------------------------------------- % function [Ck, LabCk, S] = initcenters(I, K) % [Ck, S] = gridblk(I, K); % % LabCk = zeros(length(Ck),C); % for ic=1:C % x = blkproc(I(:,:,ic), S, @(x)mean(x(:))); % LabCk(:,ic) = x(:); % end % % end % %-------------------------------------------------------------------- %-------------------------------------------------------------------------- function [Ck, LabCk] = updatecenters(ierr, Q, I) [X,Y,C] = size(I); indC = X*Y*(0:C-1); nk = length(ierr); Ck = ones(nk,2); LabCk = zeros(nk,3); for k=1:nk kk = ierr(k); [i,j] = find(Q==kk); % or ind2sub([X Y],Q==kk); % Ck(k) = sub2ind([X Y], floor(sum(i)/length(i)), floor(sum(j)/length(j))); Ck(k,:) = [floor(sum(i)/length(i)), floor(sum(j)/length(j))]; ij = sub2ind([X Y],i,j); LabCk(k,:) = mean(I(repmat(ij,[1 C])+repmat(indC,[length(ij) 1]))); end end