function GWL_SSIM = GWL_SSIM(imageRef, imageDis)
%Input : (1) imageRef: the first image being compared
% (2) imageDis: the second image being compared
%
%Output: (1) GWL_SSIM: is the similarty score calculated using GWL_SSIM algorithm. GWL_SSIM
% only considers the luminance component of images.
%-----------------------------------------------------------------------
%
%Usage:
%Given 2 test images img1 and img2. For gray-scale images, their dynamic range should be 0-255.
%For colorful images, the dynamic range of each color channel should be 0-255.
% GWL_SSIM = GWL_SSIM(img1, img2);
%-----------------------------------------------------------------------
[rows, cols, junk] = size(imageRef);
if junk == 3 %images are colorful
Y1 = 0.299 * double(imageRef(:,:,1)) + 0.587 * double(imageRef(:,:,2)) + 0.114 * double(imageRef(:,:,3));
Y2 = 0.299 * double(imageDis(:,:,1)) + 0.587 * double(imageDis(:,:,2)) + 0.114 * double(imageDis(:,:,3));
else %images are grayscale
Y1 = double(imageRef);
Y2 = double(imageDis);
end
Y1 = double(Y1);
Y2 = double(Y2);
%%%%%%%%%%%%%%%%%%%%%%%%%% Download the image %%%%%%%%%%%%%%%%%%%%%%%%%
minDimension = min(rows,cols);
F = max(1,round(minDimension / 256));
aveKernel = fspecial('average',F);
aveY1 = conv2(Y1, aveKernel,'same');
aveY2 = conv2(Y2, aveKernel,'same');
Y1 = aveY1(1:F:rows,1:F:cols);
Y2 = aveY2(1:F:rows,1:F:cols);
%%%%%%%%%%%%%%%%%%%%%%%%%% Calculate the gradient map%%%%%%%%%%%%%%%%%%%%%%%%%
dx = [1 0 -1; 1 0 -1; 1 0 -1]/3;
dy = [1 1 1; 0 0 0; -1 -1 -1]/3;%Prewitt operators
p=0.5;
IxY1 = conv2(Y1, dx, 'same');
IyY1 = conv2(Y1, dy, 'same');
gradientMap1 = abs(IxY1).^p +abs(IyY1).^p;
IxY2 = conv2(Y2, dx, 'same');
IyY2 = conv2(Y2, dy, 'same');
gradientMap2 = abs(IxY2).^p +abs(IyY2).^p;
%%%%%%%%%%%%%%%%%%%%%%%%%% Calculate the variance maps %%%%%%%%%%%%%%%%%%%%%%%%%
[M N] = size(Y1);
% automatic downsampling
f = max(1,round(min(M,N)/256));
%downsampling by f use a simple low-pass filter
if(f>1)
lpf = ones(f,f);
lpf = lpf/sum(lpf(:));
Y1 = imfilter(Y1,lpf,'symmetric','same');
Y2 = imfilter(Y2,lpf,'symmetric','same');
Y1 = Y1(1:f:end,1:f:end);
Y2 = Y2(1:f:end,1:f:end);
end
window = fspecial('gaussian', 11, 1.5);
L = 255;
K(2) = 0.8;
T2 = (K(2)*L)^2;
T3=T2./2;
window = window/sum(sum(window));
mu1= filter2(window, Y1, 'same');
mu2= filter2(window, Y2, 'same');
mu1_sq = mu1.*mu1;
mu2_sq = mu2.*mu2;
mu1_mu2 = mu1.*mu2;
sigma1_sqMap1 = filter2(window, Y1.*Y1, 'same') - mu1_sq;
sigma2_sqMap2 = filter2(window, Y2.*Y2, 'same') - mu2_sq;
sigma12 = filter2(window, Y1.*Y2, 'same') - mu1_mu2;
CompareSimMatrix=(2*sigma1_sqMap1.^1/2.*sigma2_sqMap2.^1/2 + T2)./(sigma1_sqMap1 + sigma2_sqMap2 + T2);
StrucSimtMatrix=(sigma12 + T3)./(sigma1_sqMap1.^1/2.*sigma2_sqMap2.^1/2 + T3);
%%%%%%%%%%%%%%%%%%%%%%%%%% Calculate the GWL-SSIM %%%%%%%%%%%%%%%%%%%%%%%%%
T1=280;%fixed
gradientSimMatrix = (2*gradientMap1.*gradientMap2 + T1) ./(gradientMap1.^2 + gradientMap2.^2 + T1);
Gm = max(gradientMap1, gradientMap2);
SimMatrix =gradientSimMatrix .* CompareSimMatrix.*StrucSimtMatrix.*Gm;
GWL_SSIM = sum(sum(SimMatrix)) ./ sum(sum(Gm));
quality_map=SimMatrix;
return;