图像质量评价指标 1

本文是图像质量评价,以及处理后图像与原图像的误差评价指标归纳


1. 图像质量评价测度Image / Picture Quality Measures


In this application, different image quality measures are calculated for a distorted image with reference to an original image. To test the application, a set of 20 distorted images is included in this package. The list of Image Quality measures implemented in this package include,

1. Structural Content (SC)
2. Mean Square Error (MSE)
3. Peak Signal to Noise Ratio (PSNR in dB)
4. Normalized Cross-Correlation (NCC)
5. Average Difference (AD)
6. Maximum Difference (MD)
7. Normalized Absolute Error (NAE)

Refer "Reference.png" for the mathematical expressions implemented in this package.

Original images are kept in the folder "OriginalImages".
Distorted images are kept in the folder "DistortedImages".

Cite As

Athi (2020). Image Quality Measures (https://www.mathworks.com/matlabcentral/fileexchange/25005-image-quality-measures), MATLAB Central File Exchange. Retrieved July 19, 2020.

 

function SC = StructuralContent(origImg, distImg)

origImg = double(origImg);

distImg = double(distImg);

SC = sum(sum(origImg .* origImg)) / sum(sum(distImg .* distImg));

 

function PSNR = PeakSignaltoNoiseRatio(origImg, distImg)

origImg = double(origImg);

distImg = double(distImg);

[M N] = size(origImg);

error = origImg - distImg;

MSE = sum(sum(error .* error)) / (M * N);

if(MSE > 0)

PSNR = 10*log(255*255/MSE) / log(10);

else

PSNR = 99;

end

 

Normalized Cross-Correlation (NCC)

function NK = NormalizedCrossCorrelation(origImg, distImg)

origImg = double(origImg);

distImg = double(distImg);

NK = sum(sum(origImg .* distImg)) / sum(sum(origImg .* origImg));

 

Normalized Absolute Error (NAE)

function NAE = NormalizedAbsoluteError(origImg, distImg)

origImg = double(origImg);

distImg = double(distImg);

error = origImg - distImg;

NAE = sum(sum(abs(error))) / sum(sum(origImg));

 

Average Difference (AD)

function AD = AverageDifference(origImg, distImg)

origImg = double(origImg);

distImg = double(distImg);

[M N] = size(origImg);

error = origImg - distImg;

AD = sum(sum(error)) / (M * N);

 

Maximum Difference (MD)  

function MD = MaximumDifference(origImg, distImg)

origImg = double(origImg);

distImg = double(distImg);

error = origImg - distImg;

MD = max(max(error));

 

Mean Square Error (MSE)

function MSE = MeanSquareError(origImg, distImg)

origImg = double(origImg);

distImg = double(distImg);

[M N] = size(origImg);

error = origImg - distImg;

MSE = sum(sum(error .* error)) / (M * N);

Main__test case 

clc;

clear all;

close all;

%Read Original & Distorted Images

origImg = imread('.\OriginalImages\Lena.bmp'); %读入图像

distImg = imread('.\DistortedImages\gaussian_noise_20.bmp');

%If the input image is rgb, convert it to gray image%转入灰度空间

noOfDim = ndims(origImg);

if(noOfDim == 3)

origImg = rgb2gray(origImg);

end

noOfDim = ndims(distImg);

if(noOfDim == 3)

distImg = rgb2gray(distImg);

end

%Size Validation 图像大小是否相同

origSiz = size(origImg);

distSiz = size(distImg);

sizErr = isequal(origSiz, distSiz);

if(sizErr == 0)

disp('Error: Original Image & Distorted Image should be of same dimensions');

return;

end

%Mean Square Error 计算均值平方误差

MSE = MeanSquareError(origImg, distImg);

disp('Mean Square Error = ');

disp(MSE);

%Peak Signal to Noise Ratio 计算图像峰值信噪比

PSNR = PeakSignaltoNoiseRatio(origImg, distImg);

disp('Peak Signal to Noise Ratio = ');

disp(PSNR);

%Normalized Cross-Correlation计算归一化互相关误差

NK = NormalizedCrossCorrelation(origImg, distImg);

disp('MNormalized Cross-Correlation = ');

disp(NK);

%Average Difference计算像素误差平均值

AD = AverageDifference(origImg, distImg);

disp('Average Difference = ');

disp(AD);

%Structural Content 计算结构内容

SC = StructuralContent(origImg, distImg);

disp('Structural Content = ');

disp(SC);

%Maximum Difference计算像素误差最大值

MD = MaximumDifference(origImg, distImg);

disp('Maximum Difference = ');

disp(MD);

%Normalized Absolute Error 归一化误差绝对值和

NAE = NormalizedAbsoluteError(origImg, distImg);

disp('Normalized Absolute Error = ');

disp(NAE);


 

2.Image Error Measurements图像间误差测度


测量两幅图像之间的差异

1. Mean squared error, MSE( above)均方误差
2. Root Mean squared error, RMSE(above)均方根误差
3. Peak signal to signal noise ratio, PSNR( above)
4. Mean absolute error, MAE
5. Signal to signal noise ratio, SNR
6. Universal Image Quality Index
7. Enhancement Measurement Error, EME

8. Pearson Correlation Coefficient

Cited as:https://uk.mathworks.com/matlabcentral/fileexchange/29500-image-error-measurements

2. Root Mean squared error, RMSE(above)均方根误差

function err = RMSE(signal1, signal2)

%RMSE Root Mean Squared Error

err = sum((signal1 - signal2).^2)/length(signal1); % MSE

err = sqrt(err); % RMSE

en

function [mse, rmse] = RMSE2(signal1, signal2)

originalRowSize = size(signal1,1);

originalColSize = size(signal1,2);

signal1 = signal1(:);

signal2 = signal2(:);

mse = sum((signal1 - signal2).^2)./(originalRowSize*originalColSize);

rmse = sqrt(mse);

end

3. Peak signal to signal noise ratio, PSNR( above)

function psnr_Value = PSNR(A,B)

% PSNR (Peak Signal to noise ratio)

if (size(A) ~= size(B))

error('The size of the 2 matrix are unequal')

psnr_Value = NaN;

return;

elseif (A == B)

disp('Images are identical: PSNR has infinite value')

psnr_Value = Inf;

return;

else

maxValue = double(max(A(:)));

% Calculate MSE, mean square error.

mseImage = (double(A) - double(B)) .^ 2;

[rows columns] = size(A);

mse = sum(mseImage(:)) / (rows * columns);

% Calculate PSNR (Peak Signal to noise ratio)

psnr_Value = 10 * log10( 256^2 / mse);

end

%4. Mean absolute error, MAE

function [mae] = meanAbsoluteError(signal1, signal2) 平均绝对误差

originalRowSize = size(signal1,1);

originalColSize = size(signal1,2);

signal1 = signal1(:);

signal2 = signal2(:);

mae = sum(abs(signal1 - signal2))/(originalRowSize*originalColSize);

end

%5. Signal to signal noise ratio, SNR

function snr_power = SNR(signal, noise)

% SNR (Signal to noise ratio)

[signalRowSize signalColSize] = size(signal);

[noiseRowSize noiseColSize] = size(noise);

signalAmp = signal(:);

noiseAmp = noise(:);

signalPower = sum(signalAmp.^2)/(signalRowSize*signalColSize); %信号

noisePower = sum(noiseAmp.^2)/(noiseRowSize*noiseColSize); %噪声

snr_power = 10*log10(signalPower/noisePower); %信号噪声比

end

 

%6-. Universal Image Quality Index

function [quality, quality_map] = imageQualityIndex (img1, img2, block_size)

% * Note: img_qi is renamed as imageQualityIndex

%

%Copyright (c) 2001 The University of Texas at Austin

%All Rights Reserved.

%

%Author : Zhou Wang

%Version : 1.0

%

%========================================================================

%This is an efficient implementation of the algorithm for calculating

%the universal image quality index proposed by Zhou Wang and Alan C.

%Bovik. Please refer to the paper "A Universal Image Quality Index"

%by Zhou Wang and Alan C. Bovik, published in IEEE Signal Processing

%Letters, 2001. In order to run this function, you must have Matlab's

%Image Processing Toobox.

%

%Input : an original image and a test image of the same size

%Output: (1) an overall quality index of the test image, with a value range of [-1, 1].

% (2) a quality map of the test image. The map has a smaller  size than the input images. The actual size is  img_size - BLOCK_SIZE + 1.

%Usage:
%
%1. Load the original and the test images into two matrices
%   (say img1 and img2)
%
%2. Run this function in one of the two ways:
%
%   % Choice 1 (suggested):
%   [qi qi_map] = img_qi(img1, img2);
%
%   % Choice 2:
%   [qi qi_map] = img_qi(img1, img2, BLOCK_SIZE);
%
%   The default BLOCK_SIZE is 8 (Choice 1). Otherwise, you can specify
%   it by yourself (Choice 2).
%
%3. See the results:
%
%   qi                    %Gives the over quality index.
%   imshow((qi_map+1)/2)  %Shows the quality map as an image.
%
%========================================================================
%未验证
if (nargin == 1 | nargin > 3)
   quality = -Inf;
   quality_map = -1*ones(size(img1));
   return;
end
if (size(img1) ~= size(img2))
   quality = -Inf;
   quality_map = -1*ones(size(img1));
   return;
end
if (nargin == 2)  % sliding window, B by B
   block_size = 8;
end
N = block_size.^2;
sum2_filter = ones(block_size);
img1_sq   = img1.*img1;
img2_sq   = img2.*img2;
img12 = img1.*img2;
img1_sum   = filter2(sum2_filter, img1, 'valid');
img2_sum   = filter2(sum2_filter, img2, 'valid');
img1_sq_sum = filter2(sum2_filter, img1_sq, 'valid');
img2_sq_sum = filter2(sum2_filter, img2_sq, 'valid');
img12_sum = filter2(sum2_filter, img12, 'valid');
img12_sum_mul = img1_sum.*img2_sum;
img12_sq_sum_mul = img1_sum.*img1_sum + img2_sum.*img2_sum;
numerator = 4*(N*img12_sum - img12_sum_mul).*img12_sum_mul;
denominator1 = N*(img1_sq_sum + img2_sq_sum) - img12_sq_sum_mul;
denominator = denominator1.*img12_sq_sum_mul;
quality_map = ones(size(denominator));
index = (denominator1 == 0) & (img12_sq_sum_mul ~= 0);
quality_map(index) = 2*img12_sum_mul(index)./img12_sq_sum_mul(index);
index = (denominator ~= 0);
quality_map(index) = numerator(index)./denominator(index);
quality = mean2(quality_map);

 

 

%7 -Enhancement Measurement Error, EME增强评价误差

% Call: eme(A,M,L)

% The 1st measure, EME, of enhancement calculation

% of the image X of size MxM by using blocks of size LxL用L*L的图块计算 

%

function E=eme(X,M,L);

% L=5;

how_many=floor(M/L); %图像分多少块

E=0.;

B1=zeros(L);

m1=1;

for m=1:how_many  %

n1=1;

for n=1:how_many

B1=X(m1:m1+L-1,n1:n1+L-1); %取图块

b_min=min(min(B1)); %当前图块的最小值

b_max=max(max(B1));%当前图块的最大值

if b_min>0

b_ratio=b_max/b_min; 

E=E+20.*log(b_ratio); %累加结果 

end;

n1=n1+L;

end;

m1=m1+L;

end;

E=(E/how_many)/how_many;

 

%8-Persons相关系数

function pcc = compute_PearsonCorrelationCoefficient (signal1, signal2)

originalRowSize = size(signal1,1);

originalColSize = size(signal1,2);

signal1 = signal1(:);

signal2 = signal2(:);

mean_signal1 = sum(signal1)/numel(signal1);

signal1 = signal1 - mean_signal1;

mean_signal2 = sum(signal2)/numel(signal2); %均值

signal2 = signal2 - mean_signal2; %偏差

pcc = sum(signal1.*signal2)/ (std(signal1)*std(signal2));

end

%8-其他相关系数

function imagePlot( imageData, plotRowSize, plotColSize,plotIndex, titleStr )

%IMAGEPLOT

subplot(plotRowSize, plotColSize, plotIndex);

imshow(imageData, []); title(titleStr);

end

usage_errorMeasurementsOfImages.m %主程序 

%%

clear all; clc;

%% report format characters

newlineInAscii1 = [13 10];

spaceInInAscii = 32;

% for printing, newline causes much confusion in matlab and is provided here as an alternative

newline = char(newlineInAscii1);

spaceChar = char(spaceInInAscii);

%% plot parameters

plotIndex = 1;

plotRowSize = 1;

plotColSize = 2;

%% read the image

targetFolder = 'images';

IMG = 'lena.jpg'; % IMG : originalImage

IMG = strcat(targetFolder, '\', IMG);

IMG = imread(IMG);

IMG = rgb2gray(IMG);

IMG = double(IMG);

%% noise parameters

sigma = 0.05;

offset = 0.01;

erosionFilterSize = 2;

dilationFilterSize = 2;

mean = 0;

noiseTypeModes = {

'gaussian', % [1]

'salt & pepper', % [2]

'localvar', % [3]

'speckle', % [4] (multiplicative noise)

'poisson', % [5]

'motion blur', % [6]

'erosion', % [7]

'dilation', % [8]

% 'jpg compression blocking effect' % [9]

% [10] Interpolation/ resizing noise

};

noiseChosen = 2;

noiseTypeChosen = char(noiseTypeModes(noiseChosen));

originalImage = uint8(IMG);

%% plot original

titleStr = 'Original';

imagePlot( originalImage, plotRowSize, plotColSize, ...

plotIndex, titleStr );

plotIndex = plotIndex + 1;

%%

for i = 1:(plotRowSize*plotColSize)-1

IMG_aforeUpdated = double(IMG); % backup the previous state just in case it gets updated.

% returns the noise param updates for further corruption

% IMG may be updated as the noisy image for the next round

[IMG, noisyImage, titleStr, sigma, dilationFilterSize, erosionFilterSize] = ...

noisyImageGeneration(IMG, mean, sigma, offset, dilationFilterSize, erosionFilterSize, noiseTypeChosen);

imageQualityIndex_Value = imageQualityIndex(double(originalImage), double(noisyImage));

titleStr = [titleStr ',' newline 'IQI: ' num2str(imageQualityIndex_Value)];

imagePlot( noisyImage, plotRowSize, plotColSize, ...

plotIndex, titleStr );

plotIndex = plotIndex + 1;

end

if (~strcmp(char(class(noisyImage)), 'uint8'))

disp('noisyImage is NOT type: uint8');

end

%% PSNR

psnr_Value = PSNR(originalImage, noisyImage);

fprintf('PSNR = +%5.5f dB \n', psnr_Value);

%% RMSE

[mse, rmse] = RMSE2(double(originalImage), double(noisyImage));

fprintf('MSE = %5.5f \n', mse);

fprintf('RMSE = %5.5f \n', rmse);

%% Universal Quality Index

imageQualityIndex_Value = imageQualityIndex(double(originalImage), double(noisyImage));

fprintf('Universal Image Quality Index = %5.5f \n', imageQualityIndex_Value);

%% Enhancement : measure of enhance- ment, or measure of improvement

[M M] = size(originalImage);

L = 8;

EME_original = eme(double(originalImage),M,L);

EME_noisyImage = eme(double(noisyImage),M,L);

fprintf('EME (original image) = %5.5f \n', EME_original);

fprintf('EME (noisy image) = %5.5f \n', EME_noisyImage);

%% PearsonCorrelationCoefficient

pcc = compute_PearsonCorrelationCoefficient (double(originalImage), double(noisyImage));

fprintf('PearsonCorrelationCoefficient (originalImage vs noisyImage) = %5.5f \n', pcc);

pcc = compute_PearsonCorrelationCoefficient (double(originalImage), double(originalImage));

fprintf('PearsonCorrelationCoefficient (originalImage vs originalImage) = %5.5f \n', pcc);

%% Signal to signal noise ratio, SNR

noise = double(noisyImage) - double(originalImage); % assume additive noise

% check noise

noisyImageReconstructed = double(originalImage) + noise;

residue = noisyImageReconstructed - double(noisyImage);

if (sum(residue(:) ~= 0))

disp('The noise is NOT relevant.');

end

snr_power = SNR(originalImage, noise);

fprintf('SNR = %5.5f dB \n', snr_power);

%% Mean absolute error, MAE

mae = meanAbsoluteError(double(originalImage), double(noisyImage));

fprintf('MAE = %5.5f \n', mae);

 

%产生噪声函数

function [IMG, noisyImage, titleStr, sigmaUpdated, dilationFilterSizeUpdated, erosionFilterSizeUpdated] = ...

noisyImageGeneration(IMG, mean, sigma, offset, dilationFilterSize, erosionFilterSize, noiseType)

%NOISYIMAGEGENERATION

newlineInAscii1 = [13 10];

spaceInInAscii = 32;

% for printing, newline causes much confusion in matlab and is provided here as an alternative

newline = char(newlineInAscii1);

spaceChar = char(spaceInInAscii);

noiseTypeModes = {

'gaussian',

'salt & pepper',

'localvar',

'speckle',

'poisson',

'motion blur',

'erosion',

'dilation',

'jpg compression blocking effect'

};

switch (lower(noiseType))

case char(noiseTypeModes(1))

noisyImage = imnoise(uint8(IMG),'gaussian', mean, sigma);

%adds Gaussian white noise of mean M and variance V to image I. When unspecified, M and V default to 0 and

%0.01 respectively.

titleStr = ['Noisy image using Gaussian white noise', newline, 'with sigma =',num2str(sigma)];

sigma = sigma + offset;

case char(noiseTypeModes(2))

noisyImage = imnoise(uint8(IMG), 'salt & pepper', sigma);

%adds "salt and pepper" noise to the image I, where sigma is the noise density. This affects approximately

%sigma*numel(I) pixels. Default sigma = 0.05.

titleStr = ['Noisy image using Salt & Pepper noise', newline, 'with sigma =',num2str(sigma)];

sigma = sigma + offset;

case char(noiseTypeModes(3))

imageMask = abs(sigma*randn(size(IMG))); % non-negative

titleStr = ['Noisy image using Gaussian white noise ', newline, '(with noise mask) sigma =',num2str(sigma)];

% J = imnoise(I,'localvar', V) adds zero-mean, Gaussian white noise of local variance, V, to the image I.

% V is an array of the same size as I.

noisyImage = imnoise(uint8(IMG), 'localvar', imageMask);

sigma = sigma + offset;

case char(noiseTypeModes(4))

noisyImage = imnoise(uint8(IMG), 'speckle', sigma);

%adds multiplicative noise to the image I, using the equation J = I + n*I, where n is uniformly distributed random

%noise with mean 0 and variance V. The default for V is 0.04.

titleStr = ['Noisy Image using multiplicative noise', newline, 'with sigma = ', num2str(sigma)];

sigma = sigma + offset;

case char(noiseTypeModes(5))

noisyImage = imnoise(uint8(IMG), 'poisson');

titleStr = ['Noisy Image using poisson'];

IMG = noisyImage;

case char(noiseTypeModes(6))

PSF = fspecial('motion', 500*sigma, (500*sigma)-5);

noisyImage = imfilter(IMG, PSF, 'symmetric','conv'); % 'conv', 'circular');

titleStr = ['Noisy Image using motion noise', newline, 'with sigma = ', num2str(sigma)];

sigma = sigma + offset;

case char(noiseTypeModes(7))

erosionFilter = ones(erosionFilterSize, erosionFilterSize);

noisyImage = imerode(IMG, erosionFilter);

titleStr = ['Noisy image using Erosion with filter', newline, 'size =',num2str(erosionFilterSize)];

erosionFilterSize = erosionFilterSize + 1;

case char(noiseTypeModes(8))

dilationFilter = ones(dilationFilterSize, dilationFilterSize);

noisyImage = imerode(IMG, dilationFilter);

titleStr = ['Noisy image using Dilation with filter', newline, 'size =',num2str(dilationFilterSize)];

dilationFilterSize = dilationFilterSize + 1;

case char(noiseTypeModes(9))

dilationFilterSize = 9;

outputFolder = 'outputFiles';

outputFileTarget = 'tmp.jpg';

mkdir(outputFolder);

outputFileTarget = strcat(outputFolder, '\', outputFileTarget);

imwrite(IMG/255, outputFileTarget, 'quality', dilationFilterSize);

noisyImage = double(imread(outputFileTarget));

titleStr = ['Noisy image using jpg compression blocking effect,', newline, 'blocking factor =',num2str(dilationFilterSize)];

% dilationFilterSize = dilationFilterSize + 1;

IMG = noisyImage;

delete(outputFileTarget);

end % END of noise type choice

sigmaUpdated = sigma;

dilationFilterSizeUpdated = dilationFilterSize;

erosionFilterSizeUpdated = erosionFilterSize;

end

 

你可能感兴趣的:(图像质量评价指标 1)