function [p_hvs_m, p_hvs] = psnrhvsm(img1, img2, wstep) %======================================================================== % % Calculation of PSNR-HVS-M and PSNR-HVS image quality measures % % PSNR-HVS-M is Peak Signal to Noise Ratio taking into account % Contrast Sensitivity Function (CSF) and between-coefficient % contrast masking of DCT basis functions % PSNR-HVS is Peak Signal to Noise Ratio taking into account only CSF % % Copyright(c) 2006 Nikolay Ponomarenko % All Rights Reserved % % Homepage: http://ponomarenko.info, E-mail: nikolay{}ponomarenko.info % %---------------------------------------------------------------------- % % Permission to use, copy, or modify this software and its documentation % for educational and research purposes only and without fee is hereby % granted, provided that this copyright notice and the original authors' % names appear on all copies and supporting documentation. This program % shall not be used, rewritten, or adapted as the basis of a commercial % software or hardware product without first obtaining permission of the % authors. The authors make no representations about the suitability of % this software for any purpose. It is provided "as is" without express % or implied warranty. % %---------------------------------------------------------------------- % % This is an implementation of the algorithm for calculating the PSNR-HVS-M % or PSNR-HVS between two images. Please refer to the following papers: % % PSNR-HVS-M: % [1] Nikolay Ponomarenko, Flavia Silvestri, Karen Egiazarian, Marco Carli, % Jaakko Astola, Vladimir Lukin, "On between-coefficient contrast masking % of DCT basis functions", CD-ROM Proceedings of the Third International % Workshop on Video Processing and Quality Metrics for Consumer Electronics % VPQM-07, Scottsdale, Arizona, USA, 25-26 January, 2007, 4 p. % % PSNR-HVS: % [2] K. Egiazarian, J. Astola, N. Ponomarenko, V. Lukin, F. Battisti, % M. Carli, New full-reference quality metrics based on HVS, CD-ROM % Proceedings of the Second International Workshop on Video Processing % and Quality Metrics, Scottsdale, USA, 2006, 4 p. % % Kindly report any suggestions or corrections to uagames{}mail.ru % %---------------------------------------------------------------------- % % Input : (1) img1: the first image being compared % (2) img2: the second image being compared % (3) wstep: step of 8x8 window to calculate DCT % coefficients. Default value is 8. % % Output: (1) p_hvs_m: the PSNR-HVS-M value between 2 images. % If one of the images being compared is regarded as % perfect quality, then PSNR-HVS-M can be considered as the % quality measure of the other image. % If compared images are visually undistingwished, % then PSNR-HVS-M = 100000. % (2) p_hvs: the PSNR-HVS value between 2 images. % % Default Usage: % Given 2 test images img1 and img2, whose dynamic range is 0-255 % % [p_hvs_m, p_hvs] = psnrhvsm(img1, img2); % % See the results: % % p_hvs_m % Gives the PSNR-HVS-M value % p_hvs % Gives the PSNR-HVS value % %======================================================================== if nargin < 2 p_hvs_m = -Inf; p_hvs = -Inf; return; end if size(img1) ~= size(img2) p_hvs_m = -Inf; p_hvs = -Inf; return; end if nargin > 2 step = wstep; else step = 8; % Default value is 8; end img1=double(img1); img2=double(img2); LenXY=size(img1);LenY=LenXY(1);LenX=LenXY(2); CSFCof = [1.608443, 2.339554, 2.573509, 1.608443, 1.072295, 0.643377, 0.504610, 0.421887; 2.144591, 2.144591, 1.838221, 1.354478, 0.989811, 0.443708, 0.428918, 0.467911; 1.838221, 1.979622, 1.608443, 1.072295, 0.643377, 0.451493, 0.372972, 0.459555; 1.838221, 1.513829, 1.169777, 0.887417, 0.504610, 0.295806, 0.321689, 0.415082; 1.429727, 1.169777, 0.695543, 0.459555, 0.378457, 0.236102, 0.249855, 0.334222; 1.072295, 0.735288, 0.467911, 0.402111, 0.317717, 0.247453, 0.227744, 0.279729; 0.525206, 0.402111, 0.329937, 0.295806, 0.249855, 0.212687, 0.214459, 0.254803; 0.357432, 0.279729, 0.270896, 0.262603, 0.229778, 0.257351, 0.249855, 0.259950]; % see an explanation in [2] MaskCof = [0.390625, 0.826446, 1.000000, 0.390625, 0.173611, 0.062500, 0.038447, 0.026874; 0.694444, 0.694444, 0.510204, 0.277008, 0.147929, 0.029727, 0.027778, 0.033058; 0.510204, 0.591716, 0.390625, 0.173611, 0.062500, 0.030779, 0.021004, 0.031888; 0.510204, 0.346021, 0.206612, 0.118906, 0.038447, 0.013212, 0.015625, 0.026015; 0.308642, 0.206612, 0.073046, 0.031888, 0.021626, 0.008417, 0.009426, 0.016866; 0.173611, 0.081633, 0.033058, 0.024414, 0.015242, 0.009246, 0.007831, 0.011815; 0.041649, 0.024414, 0.016437, 0.013212, 0.009426, 0.006830, 0.006944, 0.009803; 0.019290, 0.011815, 0.011080, 0.010412, 0.007972, 0.010000, 0.009426, 0.010203]; % see an explanation in [1] S1 = 0; S2 = 0; Num = 0; X=1;Y=1; while Y <= LenY-7 while X <= LenX-7 A = img1(Y:Y+7,X:X+7); B = img2(Y:Y+7,X:X+7); A_dct = dct2(A); B_dct = dct2(B); MaskA = maskeff(A,A_dct); MaskB = maskeff(B,B_dct); if MaskB > MaskA MaskA = MaskB; end X = X + step; for k = 1:8 for l = 1:8 u = abs(A_dct(k,l)-B_dct(k,l)); S2 = S2 + (u*CSFCof(k,l)).^2; % PSNR-HVS if (k~=1) | (l~=1) % See equation 3 in [1] if u < MaskA/MaskCof(k,l) u = 0; else u = u - MaskA/MaskCof(k,l); end end S1 = S1 + (u*CSFCof(k,l)).^2; % PSNR-HVS-M Num = Num + 1; end end end X = 1; Y = Y + step; end if Num ~=0 S1 = S1/Num;S2 = S2/Num; if S1 == 0 p_hvs_m = 100000; % img1 and img2 are visually undistingwished else p_hvs_m = 10*log10(255*255/S1); end if S2 == 0 p_hvs = 100000; % img1 and img2 are identical else p_hvs = 10*log10(255*255/S2); end end function m=maskeff(z,zdct) % Calculation of Enorm value (see [1]) m = 0; MaskCof = [0.390625, 0.826446, 1.000000, 0.390625, 0.173611, 0.062500, 0.038447, 0.026874; 0.694444, 0.694444, 0.510204, 0.277008, 0.147929, 0.029727, 0.027778, 0.033058; 0.510204, 0.591716, 0.390625, 0.173611, 0.062500, 0.030779, 0.021004, 0.031888; 0.510204, 0.346021, 0.206612, 0.118906, 0.038447, 0.013212, 0.015625, 0.026015; 0.308642, 0.206612, 0.073046, 0.031888, 0.021626, 0.008417, 0.009426, 0.016866; 0.173611, 0.081633, 0.033058, 0.024414, 0.015242, 0.009246, 0.007831, 0.011815; 0.041649, 0.024414, 0.016437, 0.013212, 0.009426, 0.006830, 0.006944, 0.009803; 0.019290, 0.011815, 0.011080, 0.010412, 0.007972, 0.010000, 0.009426, 0.010203]; % see an explanation in [1] for k = 1:8 for l = 1:8 if (k~=1) | (l~=1) m = m + (zdct(k,l).^2) * MaskCof(k,l); end end end pop=vari(z); if pop ~= 0 pop=(vari(z(1:4,1:4))+vari(z(1:4,5:8))+vari(z(5:8,5:8))+vari(z(5:8,1:4)))/pop; end m = sqrt(m*pop)/32; % sqrt(m*pop/16/64) function d=vari(AA) d=var(AA(:))*length(AA(:));