161 lines
6.2 KiB
C++
161 lines
6.2 KiB
C++
/*
|
|
|
|
------------------------- SSIM --------------------------------------
|
|
* The equivalent of Zhou Wang's SSIM matlab code using OpenCV.
|
|
* from http://www.cns.nyu.edu/~zwang/files/research/ssim/index.html
|
|
* The measure is described in :
|
|
* "Image quality assessment: From error measurement to structural similarity"
|
|
* C++ code by Rabah Mehdi. http://mehdi.rabah.free.fr/SSIM
|
|
*
|
|
* This implementation is under the public domain.
|
|
* @see http://creativecommons.org/licenses/publicdomain/
|
|
|
|
--------------------------- OPENCV -----------------------------------
|
|
License Agreement
|
|
For Open Source Computer Vision Library
|
|
(3-clause BSD License)
|
|
|
|
Copyright (C) 2000-2019, Intel Corporation, all rights reserved.
|
|
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
|
|
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
|
|
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
|
|
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
|
|
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
|
|
Third party copyrights are property of their respective owners.
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
are permitted provided that the following conditions are met:
|
|
|
|
* Redistributions of source code must retain the above copyright notice,
|
|
this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
|
|
* Neither the names of the copyright holders nor the names of the contributors
|
|
may be used to endorse or promote products derived from this software
|
|
without specific prior written permission.
|
|
|
|
This software is provided by the copyright holders and contributors "as is" and
|
|
any express or implied warranties, including, but not limited to, the implied
|
|
warranties of merchantability and fitness for a particular purpose are disclaimed.
|
|
In no event shall copyright holders or contributors be liable for any direct,
|
|
indirect, incidental, special, exemplary, or consequential damages
|
|
(including, but not limited to, procurement of substitute goods or services;
|
|
loss of use, data, or profits; or business interruption) however caused
|
|
and on any theory of liability, whether in contract, strict liability,
|
|
or tort (including negligence or otherwise) arising in any way out of
|
|
the use of this software, even if advised of the possibility of such damage.
|
|
|
|
=============================================================================
|
|
Copyright 2020 (c), Advanced Micro Devices, Inc. All rights reserved.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files(the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions :
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
========================================================================================
|
|
*/
|
|
|
|
#include "TestReport.h"
|
|
#include "SSIM.h"
|
|
|
|
void getMSE_PSNR( const Mat& I1, const Mat& I2, double &mse, double &psnr)
|
|
{
|
|
Mat s1;
|
|
absdiff(I1, I2, s1); // |I1 - I2|
|
|
s1.convertTo(s1, CV_32F); // cannot make a square on 8 bits
|
|
s1 = s1.mul(s1); // |I1 - I2|^2
|
|
|
|
Scalar s = sum(s1); // sum elements per channel
|
|
|
|
double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels
|
|
|
|
if( sse <= 1e-10) // for small values return zero
|
|
{
|
|
mse = 0;
|
|
psnr = 0;
|
|
}
|
|
else
|
|
{
|
|
mse = sse /(double)(I1.channels() * I1.total());
|
|
psnr = 10.0*log10((255*255)/mse);
|
|
}
|
|
}
|
|
|
|
Scalar getSSIM( const Mat& i1, const Mat& i2, CMP_Feedback_Proc pFeedbackProc)
|
|
{
|
|
const double C1 = 6.5025, C2 = 58.5225;
|
|
/***************************** INITS **********************************/
|
|
int d = CV_32F;
|
|
|
|
Mat I1, I2;
|
|
i1.convertTo(I1, d); // cannot calculate on one byte large values
|
|
i2.convertTo(I2, d);
|
|
|
|
Mat I2_2 = I2.mul(I2); // I2^2
|
|
Mat I1_2 = I1.mul(I1); // I1^2
|
|
Mat I1_I2 = I1.mul(I2); // I1 * I2
|
|
|
|
|
|
// Progress
|
|
if (pFeedbackProc)
|
|
{
|
|
if (pFeedbackProc(50.0, NULL, NULL))
|
|
return -1; //abort
|
|
}
|
|
|
|
/*************************** END INITS **********************************/
|
|
|
|
Mat mu1, mu2; // PRELIMINARY COMPUTING
|
|
GaussianBlur(I1, mu1, Size(11, 11), 1.5);
|
|
GaussianBlur(I2, mu2, Size(11, 11), 1.5);
|
|
|
|
Mat mu1_2 = mu1.mul(mu1);
|
|
Mat mu2_2 = mu2.mul(mu2);
|
|
Mat mu1_mu2 = mu1.mul(mu2);
|
|
|
|
Mat sigma1_2, sigma2_2, sigma12;
|
|
|
|
GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);
|
|
sigma1_2 -= mu1_2;
|
|
|
|
GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);
|
|
sigma2_2 -= mu2_2;
|
|
|
|
GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);
|
|
sigma12 -= mu1_mu2;
|
|
|
|
///////////////////////////////// FORMULA ////////////////////////////////
|
|
Mat t1, t2, t3;
|
|
|
|
t1 = 2 * mu1_mu2 + C1;
|
|
t2 = 2 * sigma12 + C2;
|
|
t3 = t1.mul(t2); // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))
|
|
|
|
t1 = mu1_2 + mu2_2 + C1;
|
|
t2 = sigma1_2 + sigma2_2 + C2;
|
|
t1 = t1.mul(t2); // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))
|
|
|
|
Mat ssim_map;
|
|
divide(t3, t1, ssim_map); // ssim_map = t3./t1;
|
|
|
|
Scalar mssim = mean( ssim_map ); // mssim = average of ssim map
|
|
return mssim;
|
|
}
|
|
|