matlab实现图像质量评价指标SSIM和PSNR

您所在的位置:网站首页 信噪比选定时间范围要求 matlab实现图像质量评价指标SSIM和PSNR

matlab实现图像质量评价指标SSIM和PSNR

2023-07-14 23:19| 来源: 网络整理| 查看: 265

其实使用那儿个方法计算PSNR和SSIM都无所谓!! 只要将所有算法使用同一种计算方法对照实验即可!!!!

matlab有内置函数ssim()、psnr()可以直接调用

** 在这里插入图片描述

计算psnr方法,分为三种:

**

1:计算rgb三通道每个通道的psnr值,再求平均 2:计算rgb三通道每个通道的mse值,再平均,得到psnr。** 方法一和方法二理论上计算出来的psnr应该相同,并比方法三高3左右… 3:将R,G,B格式转换为YCbCr,只计算Y分量(亮度分量),结果会比直接计算要高几个dB。 (本文章给出此方法的实现代码)

(matlab的内置psnr函数默认将图片当成灰度图像处理) 其中方法2和3用的比较多,1不常用!

方法一 (与matlab内置psnr()函数计算的峰值信噪比有略微差别!)

img=imread('src_88.png'); img = imcrop(img,[0,146,1242,230]); //img和imgn必须保证大小相同 [h,w]=size(img); imgn=imread('dehaze.png'); img=double(img); imgn=double(imgn); B=8; %编码一个像素用多少二进制位 MAX=2^B-1; %图像有多少灰度级 MES=sum(sum((img-imgn).^2))/(h*w/3); %均方差 PSNR=10*log10(MAX.^2/MES); %峰值信噪比 MAX.^2 Total_PSNR=(PSNR(:,:,1)+PSNR(:,:,2)+PSNR(:,:,3))/3; disp(Total_PSNR)

使用matlab内置psnr函数(等同于mesaerr()函数,都返回两张图片的psnr):

help psnr % 查看psnr函数详情 psnr(A, ref) % 直接使用matlab内置函数计算psnr

方法二 (与直接使用matlab内置的psnr()函数得到的峰值信噪比相同!)

X = imread('src_88.png'); X = imcrop(X,[0,146,1242,230]); %将两张图片裁剪成统一大小 Y = imread('dehaze.png'); [r,cl]=size(X); %读入图像尺寸 c=cl/3; X = double(X); Y = double(Y); mse_mR=double(zeros(r,c)); mse_mG=double(zeros(r,c)); mse_mB=double(zeros(r,c)); Xr=X(:,:,1); Xg=X(:,:,2); Xb=X(:,:,3); Yr=Y(:,:,1); Yg=Y(:,:,2); Yb=Y(:,:,3); for i=1:r for j=1:c mse_mR(i,j)=(Xr(i,j)-Yr(i,j))^2; mse_mG(i,j)=(Xg(i,j)-Yg(i,j))^2; mse_mB(i,j)=(Xb(i,j)-Yb(i,j))^2; end end mseRGB = sum(mse_mR(:))+sum(mse_mG(:))+sum(mse_mB(:)); mse = mseRGB/(r*cl); PSNR = 10*log10(255^2/mse)

方法三(如果传入RGB图像,比使用matlab内置的psnr函数得到的值要大2左右):

function [PSNR, MSE] = psnr(X, Y) %%%%%%%%%%%%%%%%%%%%%%%%%%% % % 计算峰值信噪比PSNR % 将RGB转成YCbCr格式进行计算 % 如果直接计算会比转后计算值要小2dB左右(当然是个别测试) % %%%%%%%%%%%%%%%%%%%%%%%%%%% if size(X,3)~=1 %判断图像时不是彩色图,如果是,结果为3,否则为1 org=rgb2ycbcr(X); test=rgb2ycbcr(Y); Y1=org(:,:,1); Y2=test(:,:,1); Y1=double(Y1); %计算平方时候需要转成double类型,否则uchar类型会丢失数据 Y2=double(Y2); else %灰度图像,不用转换 Y1=double(X); Y2=double(Y); end if nargin> X= imread('C:\Users\Administrator\Desktop\noise_image.jpg'); >> Y= imread('C:\Users\Administrator\Desktop\actruel_image.jpg'); >> psnr(X, Y) 计算ssim

计算SSIM的差异原因:同上,如果直接不转换成YCbCr格式,结果会偏高很多( matlab中内置ssim函数使用的方法 )。opencv里面是分别计算了R,G,B三个分量的SSIM值( 官方代码 )。最后将3个值取了个平均(这个值比matlab里面低很多)。

方法1. 直接使用matlab内置的ssim函数

help ssim % 查看ssim函数详情

在这里插入图片描述 将RGB图像转换成YCbCr计算图片的SSIM(与matlab内置的ssim函数相同)

function [ssimval, ssimmap] = ssim(varargin) %SSIM Structural Similarity Index for measuring image quality % SSIMVAL = SSIM(A, REF) calculates the Structural Similarity Index % (SSIM) value for image A, with the image REF as the reference. A and % REF can be 2D grayscale or 3D volume images, and must be of the same % size and class. % % [SSIMVAL, SSIMMAP] = SSIM(A, REF) also returns the local SSIM value for % each pixel in SSIMMAP. SSIMMAP has the same size as A. % % [SSIMVAL, SSIMMAP] = SSIM(A, REF, NAME1, VAL1,...) calculates the SSIM % value using name-value pairs to control aspects of the computation. % Parameter names can be abbreviated. % % Parameters include: % % 'Radius' - Specifies the standard deviation of % isotropic Gaussian function used for % weighting the neighborhood pixels around a % pixel for estimating local statistics. This % weighting is used to avoid blocking % artifacts in estimating local statistics. % The default value is 1.5. % % 'DynamicRange' - Positive scalar, L, that specifies the % dynamic range of the input image. By % default, L is chosen based on the class of % the input image A, as L = % diff(getrangefromclass(A)). Note that when % class of A is single or double, L = 1 by % default. % % 'RegularizationConstants'- Three-element vector, [C1 C2 C3], of % non-negative real numbers that specifies the % regularization constants for the luminance, % contrast, and structural terms (see [1]), % respectively. The regularization constants % are used to avoid instability for image % regions where the local mean or standard % deviation is close to zero. Therefore, small % non-zero values should be used for these % constants. By default, C1 = (0.01*L).^2, C2 % = (0.03*L).^2, and C3 = C2/2, where L is the % specified 'DynamicRange' value. If a value % of 'DynamicRange' is not specified, the % default value is used (see name-value pair % 'DynamicRange'). % % 'Exponents' - Three-element vector [alpha beta gamma], % of non-negative real numbers that specifies % the exponents for the luminance, contrast, % and structural terms (see [1]), % respectively. By default, all the three % exponents are 1, i.e. the vector is [1 1 % 1]. % % Notes % ----- % 1. A and REF can be arrays of upto three dimensions. All 3D arrays % are considered 3D volumetric images. RGB images will also be % processed as 3D volumetric images. % % 2. Input image A and reference image REF are converted to % floating-point type for internal computation. % % 3. For signed-integer images (int16), an offset is applied to bring the % gray values in the non-negative range before computing the SSIM % index. % % Example % --------- % This example shows how to compute SSIM value for a blurred image given % the original reference image. % % ref = imread('pout.tif'); % H = fspecial('Gaussian',[11 11],1.5); % A = imfilter(ref,H,'replicate'); % % subplot(1,2,1); imshow(ref); title('Reference Image'); % subplot(1,2,2); imshow(A); title('Blurred Image'); % % [ssimval, ssimmap] = ssim(A,ref); % % fprintf('The SSIM value is %0.4f.\n',ssimval); % % figure, imshow(ssimmap,[]); % title(sprintf('SSIM Index Map - Mean SSIM Value is %0.4f',ssimval)); % Class Support % ------------- % Input arrays A and REF must be one of the following classes: uint8, % int16, uint16, single, or double. Both A and REF must be of the same % class. They must be nonsparse. SSIMVAL is a scalar and SSIMMAP is an % array of the same size as A. Both SSIMVAL and SSIMMAP are of class % double, unless A and REF are of class single in which case SSIMVAL and % SSIMMAP are of class single. % % References: % ----------- % [1] Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image % Quality Assessment: From Error Visibility to Structural % Similarity," IEEE Transactions on Image Processing, Volume 13, % Issue 4, pp. 600- 612, 2004. % % See also IMMSE, MEAN, MEDIAN, PSNR, SUM, VAR. % Copyright 2013-2014 The MathWorks, Inc. narginchk(2,10); [A, ref, C, exponents, radius] = parse_inputs(varargin{:}); if isempty(A) ssimval = zeros(0, 'like', A); ssimmap = A; return; end if isa(A,'int16') % int16 is the only allowed signed-integer type for A and ref. % Add offset for signed-integer types to bring values in the % non-negative range. A = double(A) - double(intmin('int16')); ref = double(ref) - double(intmin('int16')); elseif isinteger(A) A = double(A); ref = double(ref); end % Gaussian weighting function gaussFilt = getGaussianWeightingFilter(radius,ndims(A)); % Weighted-mean and weighted-variance computations mux2 = imfilter(A, gaussFilt,'conv','replicate'); muy2 = imfilter(ref, gaussFilt,'conv','replicate'); muxy = mux2.*muy2; mux2 = mux2.^2; muy2 = muy2.^2; sigmax2 = imfilter(A.^2,gaussFilt,'conv','replicate') - mux2; sigmay2 = imfilter(ref.^2,gaussFilt,'conv','replicate') - muy2; sigmaxy = imfilter(A.*ref,gaussFilt,'conv','replicate') - muxy; % Compute SSIM index if (C(3) == C(2)/2) && isequal(exponents(:),ones(3,1)) % Special case: Equation 13 from [1] num = (2*muxy + C(1)).*(2*sigmaxy + C(2)); den = (mux2 + muy2 + C(1)).*(sigmax2 + sigmay2 + C(2)); if (C(1) > 0) && (C(2) > 0) ssimmap = num./den; else % Need to guard against divide-by-zero if either C(1) or C(2) is 0. isDenNonZero = (den ~= 0); ssimmap = ones(size(A)); ssimmap(isDenNonZero) = num(isDenNonZero)./den(isDenNonZero); end else % General case: Equation 12 from [1] % Luminance term if (exponents(1) > 0) num = 2*muxy + C(1); den = mux2 + muy2 + C(1); ssimmap = guardedDivideAndExponent(num,den,C(1),exponents(1)); else ssimmap = ones(size(A), 'like', A); end % Contrast term sigmaxsigmay = []; if (exponents(2) > 0) sigmaxsigmay = sqrt(sigmax2.*sigmay2); num = 2*sigmaxsigmay + C(2); den = sigmax2 + sigmay2 + C(2); ssimmap = ssimmap.*guardedDivideAndExponent(num,den,C(2),exponents(2)); end % Structure term if (exponents(3) > 0) num = sigmaxy + C(3); if isempty(sigmaxsigmay) sigmaxsigmay = sqrt(sigmax2.*sigmay2); end den = sigmaxsigmay + C(3); ssimmap = ssimmap.*guardedDivideAndExponent(num,den,C(3),exponents(3)); end end ssimval = mean(ssimmap(:)); end % ------------------------------------------------------------------------- function component = guardedDivideAndExponent(num, den, C, exponent) if C > 0 component = num./den; else component = ones(size(num),'like',num); isDenNonZero = (den ~= 0); component(isDenNonZero) = num(isDenNonZero)./den(isDenNonZero); end if (exponent ~= 1) component = component.^exponent; end end function gaussFilt = getGaussianWeightingFilter(radius,N) % Get 2D or 3D Gaussian weighting filter filtRadius = ceil(radius*3); % 3 Standard deviations include >99% of the area. filtSize = 2*filtRadius + 1; if (N < 3) % 2D Gaussian mask can be used for filtering even one-dimensional % signals using imfilter. gaussFilt = fspecial('gaussian',[filtSize filtSize],radius); else % 3D Gaussian mask [x,y,z] = ndgrid(-filtRadius:filtRadius,-filtRadius:filtRadius, ... -filtRadius:filtRadius); arg = -(x.*x + y.*y + z.*z)/(2*radius*radius); gaussFilt = exp(arg); gaussFilt(gaussFilt 3) error(message('images:validate:tooManyDimensions','A and REF',3)); end % Default values for parameters dynmRange = diff(getrangefromclass(A)); C = []; exponents = [1 1 1]; radius = 1.5; args_names = {'dynamicrange', 'regularizationconstants','exponents',... 'radius'}; for i = 3:2:nargin arg = varargin{i}; if ischar(arg) idx = find(strncmpi(arg, args_names, numel(arg))); if isempty(idx) error(message('images:validate:unknownInputString', arg)) elseif numel(idx) > 1 error(message('images:validate:ambiguousInputString', arg)) elseif numel(idx) == 1 if (i+1 > nargin) error(message('images:validate:missingParameterValue')); end if idx == 1 dynmRange = varargin{i+1}; validateattributes(dynmRange,{'numeric'},{'positive', ... 'finite', 'real', 'nonempty','scalar'}, mfilename, ... 'DynamicRange',i); dynmRange = double(dynmRange); elseif idx == 2 C = varargin{i+1}; validateattributes(C,{'numeric'},{'nonnegative','finite', ... 'real','nonempty','vector', 'numel', 3}, mfilename, ... 'RegularizationConstants',i); C = double(C); elseif idx == 3 exponents = varargin{i+1}; validateattributes(exponents,{'numeric'},{'nonnegative', ... 'finite', 'real', 'nonempty','vector', 'numel', 3}, ... mfilename,'Exponents',i); exponents = double(exponents); elseif idx == 4 radius = varargin{i+1}; validateattributes(radius,{'numeric'},{'positive','finite', ... 'real', 'nonempty','scalar'}, mfilename,'Radius',i); radius = double(radius); end end else error(message('images:validate:mustBeString')); end end % If 'RegularizationConstants' is not specified, choose default C. if isempty(C) C = [(0.01*dynmRange).^2 (0.03*dynmRange).^2 ((0.03*dynmRange).^2)/2]; end end

参考链接:

https://blog.csdn.net/xiaohaijiejie/article/details/48053595?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allbaidu_landing_v2~default-2-48053595.nonecase&utm_term=matlab%E7%9A%84ssim%E5%87%BD%E6%95%B0%E7%94%A8%E6%B3%95https://www.zhihu.com/question/41539785/answer/92954547


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3