mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 02:15:42 +01:00 
			
		
		
		
	fix SSIM metric ... by ignoring too-dark area
Roughly, if both the source and the reference areas are darker too dark (R/G/B <= ~6), they are ignored. One caveat: SSIM calculation won't work for U/V planes, which are 128-centered and not related to luminance. But WebPPlaneDistortion() enforces the conversion to RGB, if needed. Change-Id: I586c2579c475583b8c90c5baefd766b1d5aea591
This commit is contained in:
		| @@ -704,20 +704,24 @@ static WEBP_INLINE double SSIMCalculation( | ||||
|   const uint32_t w2 =  N * N; | ||||
|   const uint32_t C1 = 20 * w2; | ||||
|   const uint32_t C2 = 60 * w2; | ||||
|   const uint32_t C3 = 8 * 8 * w2;   // 'dark' limit ~= 6 | ||||
|   const uint64_t xmxm = (uint64_t)stats->xm * stats->xm; | ||||
|   const uint64_t ymym = (uint64_t)stats->ym * stats->ym; | ||||
|   const int64_t xmym = (int64_t)stats->xm * stats->ym; | ||||
|   const int64_t sxy = (int64_t)stats->xym * N - xmym;    // can be negative | ||||
|   const uint64_t sxx = (uint64_t)stats->xxm * N - xmxm; | ||||
|   const uint64_t syy = (uint64_t)stats->yym * N - ymym; | ||||
|   // we descale by 8 to prevent overflow during the fnum/fden multiply. | ||||
|   const uint64_t num_S = (2 * (uint64_t)(sxy < 0 ? 0 : sxy) + C2) >> 8; | ||||
|   const uint64_t den_S = (sxx + syy + C2) >> 8; | ||||
|   const uint64_t fnum = (2 * xmym + C1) * num_S; | ||||
|   const uint64_t fden = (xmxm + ymym + C1) * den_S; | ||||
|   const double r = (double)fnum / fden; | ||||
|   assert(r >= 0. && r <= 1.0); | ||||
|   return r; | ||||
|   if (xmxm + ymym >= C3) { | ||||
|     const int64_t xmym = (int64_t)stats->xm * stats->ym; | ||||
|     const int64_t sxy = (int64_t)stats->xym * N - xmym;    // can be negative | ||||
|     const uint64_t sxx = (uint64_t)stats->xxm * N - xmxm; | ||||
|     const uint64_t syy = (uint64_t)stats->yym * N - ymym; | ||||
|     // we descale by 8 to prevent overflow during the fnum/fden multiply. | ||||
|     const uint64_t num_S = (2 * (uint64_t)(sxy < 0 ? 0 : sxy) + C2) >> 8; | ||||
|     const uint64_t den_S = (sxx + syy + C2) >> 8; | ||||
|     const uint64_t fnum = (2 * xmym + C1) * num_S; | ||||
|     const uint64_t fden = (xmxm + ymym + C1) * den_S; | ||||
|     const double r = (double)fnum / fden; | ||||
|     assert(r >= 0. && r <= 1.0); | ||||
|     return r; | ||||
|   } | ||||
|   return 1.;   // area is too dark to contribute meaningfully | ||||
| } | ||||
|  | ||||
| double VP8SSIMFromStats(const VP8DistoStats* const stats) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user