00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "contributors.h"
00017 #include "global.h"
00018 #include "img_distortion.h"
00019 #include "enc_statistics.h"
00020
00021
00022
00023 float compute_ssim (ImageParameters *p_Img, InputParameters *p_Inp, imgpel **refImg, imgpel **encImg, int height, int width, int win_height, int win_width, int comp)
00024 {
00025
00026 static const float K1 = 0.01f, K2 = 0.03f;
00027 float max_pix_value_sqd;
00028 float C1, C2;
00029 float win_pixels = (float) (win_width * win_height);
00030 #ifdef UNBIASED_VARIANCE
00031 float win_pixels_bias = win_pixels - 1;
00032 #else
00033 float win_pixels_bias = win_pixels;
00034 #endif
00035 float mb_ssim, meanOrg, meanEnc;
00036 float varOrg, varEnc, covOrgEnc;
00037 int imeanOrg, imeanEnc, ivarOrg, ivarEnc, icovOrgEnc;
00038 float cur_distortion = 0.0;
00039 int i, j, n, m, win_cnt = 0;
00040 int overlapSize = p_Inp->SSIMOverlapSize;
00041
00042 max_pix_value_sqd = (float) (p_Img->max_pel_value_comp[comp] * p_Img->max_pel_value_comp[comp]);
00043 C1 = K1 * K1 * max_pix_value_sqd;
00044 C2 = K2 * K2 * max_pix_value_sqd;
00045
00046 for (j = 0; j <= height - win_height; j += overlapSize)
00047 {
00048 for (i = 0; i <= width - win_width; i += overlapSize)
00049 {
00050 imeanOrg = 0;
00051 imeanEnc = 0;
00052 ivarOrg = 0;
00053 ivarEnc = 0;
00054 icovOrgEnc = 0;
00055
00056 for ( n = j;n < j + win_height;n ++)
00057 {
00058 for (m = i;m < i + win_width;m ++)
00059 {
00060 imeanOrg += refImg[n][m];
00061 imeanEnc += encImg[n][m];
00062 ivarOrg += refImg[n][m] * refImg[n][m];
00063 ivarEnc += encImg[n][m] * encImg[n][m];
00064 icovOrgEnc += refImg[n][m] * encImg[n][m];
00065 }
00066 }
00067
00068 meanOrg = (float) imeanOrg / win_pixels;
00069 meanEnc = (float) imeanEnc / win_pixels;
00070
00071 varOrg = ((float) ivarOrg - ((float) imeanOrg) * meanOrg) / win_pixels_bias;
00072 varEnc = ((float) ivarEnc - ((float) imeanEnc) * meanEnc) / win_pixels_bias;
00073 covOrgEnc = ((float) icovOrgEnc - ((float) imeanOrg) * meanEnc) / win_pixels_bias;
00074
00075 mb_ssim = (float) ((2.0 * meanOrg * meanEnc + C1) * (2.0 * covOrgEnc + C2));
00076 mb_ssim /= (float) (meanOrg * meanOrg + meanEnc * meanEnc + C1) * (varOrg + varEnc + C2);
00077
00078 cur_distortion += mb_ssim;
00079 win_cnt++;
00080 }
00081 }
00082
00083 cur_distortion /= (float) win_cnt;
00084
00085 if (cur_distortion >= 1.0 && cur_distortion < 1.01)
00086 cur_distortion = 1.0;
00087
00088 return cur_distortion;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 void find_ssim (ImageParameters *p_Img, InputParameters *p_Inp, ImageStructure *ref, ImageStructure *src, DistMetric *metricSSIM)
00098 {
00099 DistortionParams *p_Dist = p_Img->p_Dist;
00100 FrameFormat *format = &ref->format;
00101
00102 metricSSIM->value[0] = compute_ssim (p_Img, p_Inp, ref->data[0], src->data[0], format->height, format->width, BLOCK_SIZE_8x8, BLOCK_SIZE_8x8, 0);
00103
00104 if (format->yuv_format != YUV400)
00105 {
00106 metricSSIM->value[1] = compute_ssim (p_Img, p_Inp, ref->data[1], src->data[1], format->height_cr, format->width_cr, p_Img->mb_cr_size_y, p_Img->mb_cr_size_x, 1);
00107 metricSSIM->value[2] = compute_ssim (p_Img, p_Inp, ref->data[2], src->data[2], format->height_cr, format->width_cr, p_Img->mb_cr_size_y, p_Img->mb_cr_size_x, 2);
00108 }
00109
00110 {
00111 accumulate_average(metricSSIM, p_Dist->frame_ctr);
00112 accumulate_avslice(metricSSIM, p_Img->type, p_Img->p_Stats->frame_ctr[p_Img->type]);
00113 }
00114 }
00115