当前位置:   article > 正文

SSIM与MS-SSIM图像评价函数_ms_ssim

ms_ssim

SSIM的全称为structural similarity index,即为结构相似性,是一种衡量两幅图像相似度的指标。该指标首先由德州大学奥斯丁分校的图像和视频工程实验室(Laboratory for Image and Video Engineering)提出。而如果两幅图像是压缩前和压缩后的图像,那么SSIM算法就可以用来评估压缩后的图像质量。


在实际应用中,一般采用高斯函数计算图像的均值、方差以及协方差,而不是采用遍历像素点的方式,以换来更高的效率。

具体步骤:

更正下协方差计算

python 代码:

  1. def keras_SSIM_cs(y_true, y_pred):
  2. axis=None
  3. gaussian = make_kernel(1.5)
  4. x = tf.nn.conv2d(y_true, gaussian, strides=[1, 1, 1, 1], padding='SAME')
  5. y = tf.nn.conv2d(y_pred, gaussian, strides=[1, 1, 1, 1], padding='SAME')
  6. u_x=K.mean(x, axis=axis)
  7. u_y=K.mean(y, axis=axis)
  8. var_x=K.var(x, axis=axis)
  9. var_y=K.var(y, axis=axis)
  10. cov_xy=cov_keras(x, y, axis)
  11. K1=0.01
  12. K2=0.03
  13. L=1 # depth of image (255 in case the image has a differnt scale)
  14. C1=(K1*L)**2
  15. C2=(K2*L)**2
  16. C3=C2/2
  17. l = ((2*u_x*u_y)+C1) / (K.pow(u_x,2) + K.pow(u_x,2) + C1)
  18. c = ((2*K.sqrt(var_x)*K.sqrt(var_y))+C2) / (var_x + var_y + C2)
  19. s = (cov_xy+C3) / (K.sqrt(var_x)*K.sqrt(var_y) + C3)
  20. return [c,s,l]
  21. def keras_MS_SSIM(y_true, y_pred):
  22. iterations = 5
  23. x=y_true
  24. y=y_pred
  25. weight = [0.0448, 0.2856, 0.3001, 0.2363, 0.1333]
  26. c=[]
  27. s=[]
  28. for i in range(iterations):
  29. cs=keras_SSIM_cs(x, y)
  30. c.append(cs[0])
  31. s.append(cs[1])
  32. l=cs[2]
  33. if(i!=4):
  34. x=tf.image.resize_images(x, (x.get_shape().as_list()[1]//(2**(i+1)), x.get_shape().as_list()[2]//(2**(i+1))))
  35. y=tf.image.resize_images(y, (y.get_shape().as_list()[1]//(2**(i+1)), y.get_shape().as_list()[2]//(2**(i+1))))
  36. c = tf.stack(c)
  37. s = tf.stack(s)
  38. cs = c*s
  39. #Normalize: suggestion from https://github.com/jorge-pessoa/pytorch-msssim/issues/2 last comment to avoid NaN values
  40. l=(l+1)/2
  41. cs=(cs+1)/2
  42. cs=cs**weight
  43. cs = tf.reduce_prod(cs)
  44. l=l**weight[-1]
  45. ms_ssim = l*cs
  46. ms_ssim = tf.where(tf.is_nan(ms_ssim), K.zeros_like(ms_ssim), ms_ssim)
  47. return K.mean(ms_ssim)

MATLAB代码:

  1. function [mssim, ssim_map] = ssim(img1, img2, K, window, L)
  2. % ========================================================================
  3. % Edited code by Adam Turcotte and Nicolas Robidoux
  4. % Laurentian University
  5. % Sudbury, ON, Canada
  6. % Last Modified: 2011-01-22
  7. % ----------------------------------------------------------------------
  8. % This code implements a refactored computation of SSIM that requires
  9. % one fewer blur (4 instead of 5), the same number of pixel-by-pixel
  10. % binary operations (10), and two fewer unary operations (6 instead of 8).
  11. %
  12. % In addition, this version reduces memory usage with in-place functions.
  13. % As a result, it supports larger input images.
  14. %========================================================================
  15. % ========================================================================
  16. % SSIM Index with automatic downsampling, Version 1.0
  17. % Copyright(c) 2009 Zhou Wang
  18. % All Rights Reserved.
  19. %
  20. % ----------------------------------------------------------------------
  21. % Permission to use, copy, or modify this software and its documentation
  22. % for educational and research purposes only and without fee is hereby
  23. % granted, provided that this copyright notice and the original authors'
  24. % names appear on all copies and supporting documentation. This program
  25. % shall not be used, rewritten, or adapted as the basis of a commercial
  26. % software or hardware product without first obtaining permission of the
  27. % authors. The authors make no representations about the suitability of
  28. % this software for any purpose. It is provided "as is" without express
  29. % or implied warranty.
  30. %----------------------------------------------------------------------
  31. %
  32. % This is an implementation of the algorithm for calculating the
  33. % Structural SIMilarity (SSIM) index between two images
  34. %
  35. % Please refer to the following paper and the website with suggested usage
  36. %
  37. % Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image
  38. % quality assessment: From error visibility to structural similarity,"
  39. % IEEE Transactios on Image Processing, vol. 13, no. 4, pp. 600-612,
  40. % Apr. 2004.
  41. %
  42. % http://www.ece.uwaterloo.ca/~z70wang/research/ssim/
  43. %
  44. % Note: This program is different from ssim_index.m, where no automatic
  45. % downsampling is performed. (downsampling was done in the above paper
  46. % and was described as suggested usage in the above website.)
  47. %
  48. % Kindly report any suggestions or corrections to zhouwang@ieee.org
  49. %
  50. %----------------------------------------------------------------------
  51. %
  52. %Input : (1) img1: the first image being compared
  53. % (2) img2: the second image being compared
  54. % (3) K: constants in the SSIM index formula (see the above
  55. % reference). defualt value: K = [0.01 0.03]
  56. % (4) window: local window for statistics (see the above
  57. % reference). default widnow is Gaussian given by
  58. % window = fspecial('gaussian', 11, 1.5);
  59. % (5) L: dynamic range of the images. default: L = 255
  60. %
  61. %Output: (1) mssim: the mean SSIM index value between 2 images.
  62. % If one of the images being compared is regarded as
  63. % perfect quality, then mssim can be considered as the
  64. % quality measure of the other image.
  65. % If img1 = img2, then mssim = 1.
  66. % (2) ssim_map: the SSIM index map of the test image. The map
  67. % has a smaller size than the input images. The actual size
  68. % depends on the window size and the downsampling factor.
  69. %
  70. %Basic Usage:
  71. % Given 2 test images img1 and img2, whose dynamic range is 0-255
  72. %
  73. % [mssim, ssim_map] = ssim(img1, img2);
  74. %
  75. %Advanced Usage:
  76. % User defined parameters. For example
  77. %
  78. % K = [0.05 0.05];
  79. % window = ones(8);
  80. % L = 100;
  81. % [mssim, ssim_map] = ssim(img1, img2, K, window, L);
  82. %
  83. %Visualize the results:
  84. %
  85. % mssim %Gives the mssim value
  86. % imshow(max(0, ssim_map).^4) %Shows the SSIM index map
  87. %========================================================================
  88. if (nargin < 2 || nargin > 5)
  89. mssim = -Inf;
  90. ssim_map = -Inf;
  91. return;
  92. end
  93. if (size(img1) ~= size(img2))
  94. mssim = -Inf;
  95. ssim_map = -Inf;
  96. return;
  97. end
  98. [M N] = size(img1);
  99. if (nargin == 2)
  100. if ((M < 11) || (N < 11))
  101. mssim = -Inf;
  102. ssim_map = -Inf;
  103. return
  104. end
  105. window = fspecial('gaussian', 11, 1.5); %
  106. K(1) = 0.01; % default settings
  107. K(2) = 0.03; %
  108. L = 255; %
  109. end
  110. if (nargin == 3)
  111. if ((M < 11) || (N < 11))
  112. mssim = -Inf;
  113. ssim_map = -Inf;
  114. return
  115. end
  116. window = fspecial('gaussian', 11, 1.5);
  117. L = 255;
  118. if (length(K) == 2)
  119. if (K(1) < 0 || K(2) < 0)
  120. mssim = -Inf;
  121. ssim_map = -Inf;
  122. return;
  123. end
  124. else
  125. mssim = -Inf;
  126. ssim_map = -Inf;
  127. return;
  128. end
  129. end
  130. if (nargin == 4)
  131. [H W] = size(window);
  132. if ((H*W) < 4 || (H > M) || (W > N))
  133. mssim = -Inf;
  134. ssim_map = -Inf;
  135. return
  136. end
  137. L = 255;
  138. if (length(K) == 2)
  139. if (K(1) < 0 || K(2) < 0)
  140. mssim = -Inf;
  141. ssim_map = -Inf;
  142. return;
  143. end
  144. else
  145. mssim = -Inf;
  146. ssim_map = -Inf;
  147. return;
  148. end
  149. end
  150. if (nargin == 5)
  151. [H W] = size(window);
  152. if ((H*W) < 4 || (H > M) || (W > N))
  153. mssim = -Inf;
  154. ssim_map = -Inf;
  155. return
  156. end
  157. if (length(K) == 2)
  158. if (K(1) < 0 || K(2) < 0)
  159. mssim = -Inf;
  160. ssim_map = -Inf;
  161. return;
  162. end
  163. else
  164. mssim = -Inf;
  165. ssim_map = -Inf;
  166. return;
  167. end
  168. end
  169. img1 = double(img1);
  170. img2 = double(img2);
  171. % automatic downsampling
  172. f = max(1,round(min(M,N)/256));
  173. %downsampling by f
  174. %use a simple low-pass filter
  175. if(f>1)
  176. lpf = ones(f,f);
  177. lpf = (1./(f*f))*lpf;
  178. img1 = imfilter(img1,lpf,'symmetric','same');
  179. img2 = imfilter(img2,lpf,'symmetric','same');
  180. img1 = img1(1:f:end,1:f:end);
  181. img2 = img2(1:f:end,1:f:end);
  182. end
  183. C1 = (K(1)*L)^2;
  184. C2 = (K(2)*L)^2;
  185. window = window/sum(sum(window));
  186. ssim_map = filter2(window, img1, 'valid'); % gx
  187. w1 = filter2(window, img2, 'valid'); % gy
  188. w2 = ssim_map.*w1; % gx*gy
  189. w2 = 2*w2+C1; % 2*(gx*gy)+C1 = num1
  190. w1 = (w1-ssim_map).^2+w2; % (gy-gx)^2+num1 = den1
  191. ssim_map = filter2(window, img1.*img2, 'valid'); % g(x*y)
  192. ssim_map = (2*ssim_map+(C1+C2))-w2; % 2*g(x*y)+(C1+C2)-num1 = num2
  193. ssim_map = ssim_map.*w2; % num
  194. img1 = img1.^2; % x^2
  195. img2 = img2.^2; % y^2
  196. img1 = img1+img2; % x^2+y^2
  197. if (C1 > 0 && C2 > 0)
  198. w2 = filter2(window, img1, 'valid'); % g(x^2+y^2)
  199. w2 = w2-w1+(C1+C2); % den2
  200. w2 = w2.*w1; % den
  201. ssim_map = ssim_map./w2; % num/den = ssim
  202. else
  203. w3 = filter2(window, img1, 'valid'); % g(x^2+y^2)
  204. w3 = w3-w1+(C1+C2); % den2
  205. w4 = ones(size(w1));
  206. index = (w1.*w3 > 0);
  207. w4(index) = (ssim_map(index))./(w1(index).*w3(index));
  208. index = (w1 ~= 0) & (w3 == 0);
  209. w4(index) = w2(index)./w1(index);
  210. ssim_map = w4;
  211. end
  212. mssim = mean2(ssim_map);
  213. return

C++代码

  1. #include <opencv2/imgproc/imgproc.hpp>
  2. #include <opencv2/core/core.hpp>
  3. #include <opencv2/highgui/highgui.hpp>
  4. #include <iostream>
  5. using namespace std;
  6. using namespace cv;
  7. Scalar getMSSIM(Mat inputimage1, Mat inputimage2);
  8. int main()
  9. {
  10. Mat BlurImage1;
  11. Mat BlurImage2;
  12. Mat SrcImage = imread("1.jpg");
  13. blur(SrcImage, BlurImage1, Size(5, 5));
  14. blur(SrcImage,BlurImage2,Size(10,10));
  15. Scalar SSIM1 = getMSSIM(SrcImage, BlurImage1);
  16. Scalar SSIM2 = getMSSIM(SrcImage, BlurImage2);
  17. printf("模糊5*5通道1:%f\n", SSIM1.val[0] * 100);
  18. printf("模糊5*5通道2:%f\n", SSIM1.val[1] * 100);
  19. printf("模糊5*5通道3:%f\n", SSIM1.val[2] * 100);
  20. printf("模糊5*5:%f\n", (SSIM1.val[2] + SSIM1.val[1] + SSIM1.val[0])/3 * 100);
  21. printf("模糊10*10通道1:%f\n", SSIM2.val[0] * 100);
  22. printf("模糊10*10通道2:%f\n", SSIM2.val[1] * 100);
  23. printf("模糊10*10通道3:%f\n", SSIM2.val[2] * 100);
  24. printf("模糊10*10:%f\n", (SSIM2.val[2] + SSIM2.val[1] + SSIM2.val[0]) / 3 * 100);
  25. imshow("原图",SrcImage);
  26. imshow("模糊5*5",BlurImage1);
  27. imshow("模糊10*10", BlurImage2);
  28. waitKey(0);
  29. return 0;
  30. }
  31. Scalar getMSSIM(Mat inputimage1, Mat inputimage2)
  32. {
  33. Mat i1 = inputimage1;
  34. Mat i2 = inputimage2;
  35. const double C1 = 6.5025, C2 = 58.5225;
  36. int d = CV_32F;
  37. Mat I1, I2;
  38. i1.convertTo(I1, d);
  39. i2.convertTo(I2, d);
  40. Mat I2_2 = I2.mul(I2);
  41. Mat I1_2 = I1.mul(I1);
  42. Mat I1_I2 = I1.mul(I2);
  43. Mat mu1, mu2;
  44. GaussianBlur(I1, mu1, Size(11, 11), 1.5);
  45. GaussianBlur(I2, mu2, Size(11, 11), 1.5);
  46. Mat mu1_2 = mu1.mul(mu1);
  47. Mat mu2_2 = mu2.mul(mu2);
  48. Mat mu1_mu2 = mu1.mul(mu2);
  49. Mat sigma1_2, sigma2_2, sigma12;
  50. GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);
  51. sigma1_2 -= mu1_2;
  52. GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);
  53. sigma2_2 -= mu2_2;
  54. GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);
  55. sigma12 -= mu1_mu2;
  56. Mat t1, t2, t3;
  57. t1 = 2 * mu1_mu2 + C1;
  58. t2 = 2 * sigma12 + C2;
  59. t3 = t1.mul(t2);
  60. t1 = mu1_2 + mu2_2 + C1;
  61. t2 = sigma1_2 + sigma2_2 + C2;
  62. t1 = t1.mul(t2);
  63. Mat ssim_map;
  64. divide(t3, t1, ssim_map);
  65. Scalar mssim = mean(ssim_map);
  66. return mssim;
  67. }

这里附一个Python的工具箱,有各种评价函数:

The following metrics are included:

  • Mean-Squared-Error (MSE).

  • Peak-Signal-to-Noise-Ratio (PSNR).

  • Structural Similarity Index (SSIM).

  • Normalized Mutual Information (NMI).

  • Image Complexity.

  • Resolution analysis through Edge-Profile-Fitting (EPF).

  • Resolution analysis through Fourier Ring Correlation (FRC).

The following routines to construct simulated datasets are included:

  • Create a Shepp-Logan phantom.

  • Create generic phantoms with analytical X-ray transform.

  • Rescale image.

  • Downsample sinogram.

  • Add Gaussian or Poisson noise.

  • Add Gaussian blurring.

   https://github.com/arcaduf/image_quality_assessment

【1】https://ieeexplore.ieee.org/abstract/document/1292216

 【2】Image quality assessment: From error visibility to structural similarity,

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/192973
推荐阅读
相关标签
  

闽ICP备14008679号