ssim.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * Copyright (c) 2011, Tom Distler (http://tdistler.com)
  3. * All rights reserved.
  4. *
  5. * The BSD License
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * - Redistributions of source code must retain the above copyright notice,
  11. * this list of conditions and the following disclaimer.
  12. *
  13. * - Redistributions in binary form must reproduce the above copyright notice,
  14. * this list of conditions and the following disclaimer in the documentation
  15. * and/or other materials provided with the distribution.
  16. *
  17. * - Neither the name of the tdistler.com nor the names of its contributors may
  18. * be used to endorse or promote products derived from this software without
  19. * specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  22. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  25. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  29. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  30. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. * POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #ifndef _SSIM_H_
  34. #define _SSIM_H_
  35. #include "convolve.h"
  36. /*
  37. * Circular-symmetric Gaussian weighting.
  38. * h(x,y) = hg(x,y)/SUM(SUM(hg)) , for normalization to 1.0
  39. * hg(x,y) = e^( -0.5*( (x^2+y^2)/sigma^2 ) ) , where sigma was 1.5
  40. */
  41. #define GAUSSIAN_LEN 11
  42. static const float g_gaussian_window[GAUSSIAN_LEN][GAUSSIAN_LEN] = {
  43. {0.000001f, 0.000008f, 0.000037f, 0.000112f, 0.000219f, 0.000274f, 0.000219f, 0.000112f, 0.000037f, 0.000008f, 0.000001f},
  44. {0.000008f, 0.000058f, 0.000274f, 0.000831f, 0.001619f, 0.002021f, 0.001619f, 0.000831f, 0.000274f, 0.000058f, 0.000008f},
  45. {0.000037f, 0.000274f, 0.001296f, 0.003937f, 0.007668f, 0.009577f, 0.007668f, 0.003937f, 0.001296f, 0.000274f, 0.000037f},
  46. {0.000112f, 0.000831f, 0.003937f, 0.011960f, 0.023294f, 0.029091f, 0.023294f, 0.011960f, 0.003937f, 0.000831f, 0.000112f},
  47. {0.000219f, 0.001619f, 0.007668f, 0.023294f, 0.045371f, 0.056662f, 0.045371f, 0.023294f, 0.007668f, 0.001619f, 0.000219f},
  48. {0.000274f, 0.002021f, 0.009577f, 0.029091f, 0.056662f, 0.070762f, 0.056662f, 0.029091f, 0.009577f, 0.002021f, 0.000274f},
  49. {0.000219f, 0.001619f, 0.007668f, 0.023294f, 0.045371f, 0.056662f, 0.045371f, 0.023294f, 0.007668f, 0.001619f, 0.000219f},
  50. {0.000112f, 0.000831f, 0.003937f, 0.011960f, 0.023294f, 0.029091f, 0.023294f, 0.011960f, 0.003937f, 0.000831f, 0.000112f},
  51. {0.000037f, 0.000274f, 0.001296f, 0.003937f, 0.007668f, 0.009577f, 0.007668f, 0.003937f, 0.001296f, 0.000274f, 0.000037f},
  52. {0.000008f, 0.000058f, 0.000274f, 0.000831f, 0.001619f, 0.002021f, 0.001619f, 0.000831f, 0.000274f, 0.000058f, 0.000008f},
  53. {0.000001f, 0.000008f, 0.000037f, 0.000112f, 0.000219f, 0.000274f, 0.000219f, 0.000112f, 0.000037f, 0.000008f, 0.000001f},
  54. };
  55. /*
  56. * Equal weight square window.
  57. * Each pixel is equally weighted (1/64) so that SUM(x) = 1.0
  58. */
  59. #define SQUARE_LEN 8
  60. static const float g_square_window[SQUARE_LEN][SQUARE_LEN] = {
  61. {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f},
  62. {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f},
  63. {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f},
  64. {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f},
  65. {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f},
  66. {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f},
  67. {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f},
  68. {0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f, 0.015625f},
  69. };
  70. /* Holds intermediate SSIM values for map-reduce operation. */
  71. struct _ssim_int {
  72. double l;
  73. double c;
  74. double s;
  75. };
  76. /* Defines the pointers to the map-reduce functions. */
  77. typedef int (*_map)(const struct _ssim_int *, void *);
  78. typedef float (*_reduce)(int, int, void *);
  79. /* Arguments for map-reduce. The 'context' is user-defined. */
  80. struct _map_reduce {
  81. _map map;
  82. _reduce reduce;
  83. void *context;
  84. };
  85. /**
  86. * Private method that calculates the SSIM value on a pre-processed image.
  87. *
  88. * The input images must have stride==width. This method does not scale.
  89. *
  90. * @note Image buffers are modified.
  91. *
  92. * Map-reduce is used for doing the final SSIM calculation. The map function is
  93. * called for every pixel, and the reduce is called at the end. The context is
  94. * caller-defined and *not* modified by this method.
  95. *
  96. * @param ref Original reference image
  97. * @param cmp Distorted image
  98. * @param w Width of the images
  99. * @param h Height of the images
  100. * @param k The kernel used as the window function
  101. * @param mr Optional map-reduce functions to use to calculate SSIM. Required
  102. * if 'args' is not null. Ignored if 'args' is null.
  103. * @param args Optional SSIM arguments for fine control of the algorithm. 0 for defaults.
  104. * Defaults are a=b=g=1.0, L=255, K1=0.01, K2=0.03
  105. * @return The mean SSIM over the entire image (MSSIM), or INFINITY if error.
  106. */
  107. float _iqa_ssim(float *ref, float *cmp, int w, int h, const struct _kernel *k, const struct _map_reduce *mr, const struct iqa_ssim_args *args);
  108. #endif /* _SSIM_H_ */