img_dist_ssim.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:4k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  * file img_dist_ssim.c
  4.  *
  5.  * brief
  6.  *    Compute structural similarity (SSIM) index using the encoded image and the reference image
  7.  *
  8.  * author
  9.  *    Main contributors (see contributors.h for copyright, address and affiliation details)
  10.  *     - Woo-Shik Kim                    <wooshik.kim@usc.edu>
  11.  *     - Zhen Li                         <zli@dolby.com> 
  12.  *     - Alexis Michael Tourapis         <alexismt@ieee.org>
  13.  *************************************************************************************
  14.  */
  15. #include "contributors.h"
  16. #include "global.h"
  17. #include "img_distortion.h"
  18. #include "enc_statistics.h"
  19. //#define UNBIASED_VARIANCE // unbiased estimation of the variance
  20. float compute_ssim (imgpel **refImg, imgpel **encImg, int height, int width, int win_height, int win_width, int comp)
  21. {
  22.   static const float K1 = 0.01f, K2 = 0.03f;
  23.   static float max_pix_value_sqd;
  24.   float C1, C2;
  25.   float win_pixels = (float) (win_width * win_height);
  26. #ifdef UNBIASED_VARIANCE
  27.   float win_pixels_bias = win_pixels - 1;
  28. #else
  29.   float win_pixels_bias = win_pixels;
  30. #endif
  31.   float mb_ssim, meanOrg, meanEnc;
  32.   float varOrg, varEnc, covOrgEnc;
  33.   int imeanOrg, imeanEnc, ivarOrg, ivarEnc, icovOrgEnc;
  34.   float cur_distortion = 0.0;
  35.   int i, j, n, m, win_cnt = 0;
  36.   int overlapSize = params->SSIMOverlapSize;
  37.   max_pix_value_sqd = (float) (img->max_imgpel_value_comp[comp] * img->max_imgpel_value_comp[comp]);
  38.   C1 = K1 * K1 * max_pix_value_sqd;
  39.   C2 = K2 * K2 * max_pix_value_sqd;
  40.   for (j = 0; j <= height - win_height; j += overlapSize)
  41.   {
  42.     for (i = 0; i <= width - win_width; i += overlapSize)
  43.     {
  44.       imeanOrg = 0;
  45.       imeanEnc = 0; 
  46.       ivarOrg  = 0;
  47.       ivarEnc  = 0;
  48.       icovOrgEnc = 0;
  49.       for ( n = j;n < j + win_height;n ++)
  50.       {
  51.         for (m = i;m < i + win_width;m ++)
  52.         {
  53.           imeanOrg   += refImg[n][m];
  54.           imeanEnc   += encImg[n][m];
  55.           ivarOrg    += refImg[n][m] * refImg[n][m];
  56.           ivarEnc    += encImg[n][m] * encImg[n][m];
  57.           icovOrgEnc += refImg[n][m] * encImg[n][m];
  58.         }
  59.       }
  60.       meanOrg = (float) imeanOrg / win_pixels;
  61.       meanEnc = (float) imeanEnc / win_pixels;
  62.       varOrg    = ((float) ivarOrg - ((float) imeanOrg) * meanOrg) / win_pixels_bias;
  63.       varEnc    = ((float) ivarEnc - ((float) imeanEnc) * meanEnc) / win_pixels_bias;
  64.       covOrgEnc = ((float) icovOrgEnc - ((float) imeanOrg) * meanEnc) / win_pixels_bias;
  65.       mb_ssim  = (float) ((2.0 * meanOrg * meanEnc + C1) * (2.0 * covOrgEnc + C2));
  66.       mb_ssim /= (float) (meanOrg * meanOrg + meanEnc * meanEnc + C1) * (varOrg + varEnc + C2);
  67.       cur_distortion += mb_ssim;
  68.       win_cnt++;
  69.     }
  70.   }
  71.   cur_distortion /= (float) win_cnt;
  72.   if (cur_distortion >= 1.0 && cur_distortion < 1.01) // avoid float accuracy problem at very low QP(e.g.2)
  73.     cur_distortion = 1.0;
  74.   return cur_distortion;
  75. }
  76. /*!
  77.  ************************************************************************
  78.  * brief
  79.  *    Find SSIM for all three components
  80.  ************************************************************************
  81.  */
  82. void find_ssim (ImageStructure *ref, ImageStructure *src, DistMetric *metricSSIM)
  83. {
  84.   FrameFormat *format = &ref->format;
  85.   metricSSIM->value[0] = compute_ssim (ref->data[0], src->data[0], format->height, format->width, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, 0);
  86.   // Chroma.
  87.   if (format->yuv_format != YUV400)
  88.   {     
  89.     metricSSIM->value[1]  = compute_ssim (ref->data[1], src->data[1], format->height_cr, format->width_cr, img->mb_cr_size_y, img->mb_cr_size_x, 1);
  90.     metricSSIM->value[2]  = compute_ssim (ref->data[2], src->data[2], format->height_cr, format->width_cr, img->mb_cr_size_y, img->mb_cr_size_x, 2);
  91.   }
  92.   {
  93.     accumulate_average(metricSSIM,  dist->frame_ctr);
  94.     accumulate_avslice(metricSSIM,  img->type, stats->frame_ctr[img->type]);
  95.   }
  96. }