function Iout=scorfilt(I)
% SPATIAL CORRELATION FILTER
%
% IN
% I: Image to filter, (RGB color or grayscale)
% %
% OUT
% Iout: Filtered image (double)
%
% EXAMPLE:
%
% %read image
% imfile = fullfile(matlabroot,...
% 'toolbox','images','imdemos','greens.jpg');
% Io=im2double(imread(imfile));
% %add noise
% sigma_n=20; %noise std. dev.
% randn('seed', 0);
% I=Io+sigma_n/255*randn(size(Io));
% figure('Name', 'input'), imshow(I);
% %filter image
% Iout = scorfilt(I);
% figure('Name', 'output'), imshow(Iout);
%
% Author: Carlos Estrada
% Date: May 25, 2012
% Version 1.0
%
%% Configuration
r_max=5; %max. half-size window
c=1/5; %c 'neighborhood' constant default value
%% labels
I=im2double(I);
[m n ch]=size(I);
if ch==1 %gray scale
maxI=max(I(:));
minI=min(I(:));
bins=255; %quantization bins
Ieq=uint8((bins-1)*histeq((I-minI)./(maxI-minI), bins))+1;
labels=zeros(m,n,'uint8');
N=0;
bin_mark=zeros(bins,1,'uint8');
for i=1:m
for j=1:n
id=Ieq(i,j);
if bin_mark(id)==0
N=N+1;
labels(i,j)=N;
bin_mark(id)=N;
else
labels(i,j)=bin_mark(id);
end
end
end
elseif ch==3 %color
% maxI=max(I(:));
% minI=min(I(:));
% Ifit=(I-minI)/(maxI-minI);
bins=255; %quantization bins
[labels, centers] = rgb2ind(I,bins,'nodither');
N=size(centers,1);
labels=labels+1;
end
%% adjacency matrix
Acum=zeros(N,'uint32');
for i=1:m
for j=1:n
a=labels(i,j);
if i>1
e=labels(i-1,j);
Acum(a,e)=Acum(a,e)+1;
end
if j>1
e=labels(i,j-1);
Acum(a,e)=Acum(a,e)+1;
end
end
end
A=double(Acum+Acum');
h4=sum(A,2);
P=A./repmat(h4,1,N); %transition matrix
Q=((P+P')./2)^2;
%% neighborhood size
teta=diag(P)'*h4./sum(h4);
w=sqrt((1-teta)/teta);
sigma_d=c*w;
r=max(1,min(r_max,round(sigma_d*2.5)));
%fprintf('\tN: %d\tw: %.4f\tsigma_d: %.4f', N,w,sigma_d);
%% compute Iout
Iout=zeros(m,n,ch);
[x,y] = meshgrid(-r:r,-r:r);
F=exp(-(x.^2 + y.^2)./(2*sigma_d^2));
for i=1:m
iMin = max(i-r,1);
iMax = min(i+r,m);
di=iMin:iMax;
for j=1:n
jMin = max(j-r,1);
jMax = min(j+r,n);
dj=jMin:jMax;
a=labels(i,j);
l = labels(di,dj);
f=F(di-i+r+1,dj-j+r+1);
w=Q(l(:),a).*f(:);
w=w./sum(w);
y=I(di,dj,:);
for cc=1:ch
yc=y(:,:,cc);
Iout(i,j,cc)=w'*yc(:);
end
end
end