diff --git a/README.md b/README.md index 978c70b..cdb8012 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,7 @@ Includes metrics: - MSE / MAX^2, MAX = 255 - PSNR -- MSE / MAX^2 of correlation, MAX = 255 -- PSNR of correlation +- SDSNR - [SSIM](https://github.com/rolinh/VQMT) - [VIFP1](https://github.com/rolinh/VQMT) - [SMALLFRY](https://github.com/dwbuiten/smallfry) @@ -19,7 +18,7 @@ Includes metrics: The value of MSE metrics is from 0.0 (minimum difference) to 1.0 (maximum difference). -The value of PSNR metrics is from 0.0 (maximum difference) to inf. +The value of PSNR and SDSNR metrics is from 0.0 (maximum difference) to inf. The value of [SSIM](https://github.com/rolinh/VQMT) and [VIFP1](https://github.com/rolinh/VQMT) metrics is from 1.0 (minimum difference) to 0.0 (maximum difference). @@ -103,16 +102,17 @@ stbnhwmetrics ${IMAGE_ORIG_PATH} ${IMAGE_COMPARE_PATH} [metric.out.png] Trends: ``` - UM = 0.148 * sqrt(sqrt(1.0 / MSE)) - 0.53 - UM = 0.94 * sqrt(PNSR) - 4.94 - UM = 8.57 * cor_sigma(cor_sigma(cor_sigma(SSIM))) + 0.34 - UM = 2.21 * cor_sigma(VIFP1) + 0.36 - UM = 0.0735 * SMALLFRY - 6.50 - UM = 1.46 * SHARPENBAD - 0.04 - UM = 3.92 * cor_sigma(cor_sigma(COR)) - 1.79 - UM = -0.049 * sqrt(sqrt(1.0 / NHW-N)) + 0.83 - UM = 1.36 * sqrt(sqrt(1.0 / NHW-C)) - 2.61 - UM = 0.96 * sqrt(sqrt(1.0 / NHW-R)) - 1.98 + UM = 0.158 * sqrt(sqrt(1.0 / MSE)) - 0.63 + UM = 0.99 * sqrt(PNSR) - 5.28 + UM = 0.85 * sqrt(SDNSR) - 3.84 + UM = 9.14 * cor_sigma(cor_sigma(cor_sigma(SSIM))) + 0.30 + UM = 2.36 * cor_sigma(VIFP1) + 0.32 + UM = 0.0777 * SMALLFRY - 6.93 + UM = 1.53 * SHARPENBAD - 0.09 + UM = 4.14 * cor_sigma(cor_sigma(COR)) - 1.94 + UM = -0.055 * sqrt(sqrt(1.0 / NHW-N)) + 0.82 + UM = 1.43 * sqrt(sqrt(1.0 / NHW-C)) - 2.82 + UM = 1.03 * sqrt(sqrt(1.0 / NHW-R)) - 2.17 cor_sigma(M) = 1.0 - sqrt(1.0 - M * M) ``` @@ -135,18 +135,17 @@ Save png: lena.quant444.psnr.png ``` -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.mse.png) MSE: 0.013604, UM: -0.090790 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.mse-c.png) MSE-C: 0.006495, UM: -0.001628 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.psnr.png) PSNR: 18.663233, UM: -0.879109 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.psnr-c.png) PSNR-C: 21.873943, UM: -0.543659 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.cor.png) Corelation: 0.953666, UM: -0.672773 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.ssim.png) SSIM: 0.618509, UM: 0.342309 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.vifp1.png) VIFP1: 0.170903, UM: 0.392514 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.smallfry.png) SMALLFRY: 83.753342, UM: -0.344130 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.shbad.png) SHARPENBAD: -0.213132, UM: -0.351173 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.nhw-n.png) NHW-N: 0.072673, UM: 0.735626 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.nhw-c.png) NHW-C: 0.145290, UM: -0.407173 -* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.nhw-r.png) NHW-R: 0.116387, UM: -0.336402 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.mse.png) MSE: 0.013604, UM: -0.167366 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.psnr.png) PSNR: 18.663233, UM: -1.003105 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.sdsnr.png) SDSNR: 13.888971, UM: -0.672228 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.cor.png) Corelation: 0.953666, UM: -0.760071 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.ssim.png) SSIM: 0.618509, UM: 0.302463 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.vifp1.png) VIFP1: 0.170903, UM: 0.354721 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.smallfry.png) SMALLFRY: 83.753342, UM: -0.422366 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.shbad.png) SHARPENBAD: -0.213132, UM: -0.416092 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.nhw-n.png) NHW-N: 0.072673, UM: 0.714070 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.nhw-c.png) NHW-C: 0.145290, UM: -0.503793 +* ![metric](https://raw.githubusercontent.com/ImageProcessing-ElectronicPublications/stb-image-metrics-demo/main/images/lena.quant444.nhw-r.png) NHW-R: 0.116387, UM: -0.406557 --- diff --git a/man/man1/stbimmetrics.1 b/man/man1/stbimmetrics.1 index d789f2d..8054441 100644 --- a/man/man1/stbimmetrics.1 +++ b/man/man1/stbimmetrics.1 @@ -1,4 +1,4 @@ -.TH "StbImMetrics" 1 0.3.0 "13 Jan 2023" "User Manual" +.TH "StbImMetrics" 1 0.3.1 "15 Jan 2023" "User Manual" .SH NAME stbimmetrics @@ -9,8 +9,7 @@ This utility compares two graphics files based on metrics. Includes metrics: - MSE / MAX^2, MAX = 255 - PSNR - - MSE / MAX^2 of correlation, MAX = 255 - - PSNR of correlation + - SDSNR - SSIM - VIFP1 - SMALLFRY @@ -37,12 +36,14 @@ stbimmetrics [options] ${IMAGE_ORIG_PATH} ${IMAGE_COMPARE_PATH} [metric.out.png] .SH OPTIONS .TP +-c +correlation mode: for MSE, PSNR, SDSNR +.TP -m STR metric (default psnr): mse - MSE / MAX^2, MAX = 255 psnr - PSNR - mse-c - MSE / MAX^2 of correlation, MAX = 255 - psnr-c - PSNR of correlation + sdsnr - Standard deviation as SNR ssim - SSIM vifp1 - VIFP 1 layer smallfry - SMALLFRY @@ -93,18 +94,18 @@ stbnhwmetrics -m nhw-r lena.png lena.quant444.png lena.quant444.nhw-r.png .PP Trends: - UM = 0.148 * sqrt(sqrt(1.0 / MSE)) - 0.53 - UM = 0.94 * sqrt(PNSR) - 4.94 - UM = 8.57 * cor_sigma(cor_sigma(cor_sigma(SSIM))) + 0.34 - UM = 2.21 * cor_sigma(VIFP1) + 0.36 - UM = 0.0735 * SMALLFRY - 6.50 - UM = 1.46 * SHARPENBAD - 0.04 - UM = 3.92 * cor_sigma(cor_sigma(COR)) - 1.79 - UM = -0.049 * sqrt(sqrt(1.0 / NHW-N)) + 0.83 - UM = 1.36 * sqrt(sqrt(1.0 / NHW-C)) - 2.61 - UM = 0.96 * sqrt(sqrt(1.0 / NHW-R)) - 1.98 - - cor_sigma(M) = 1.0 - sqrt(1.0 - M * M) + UM = 0.158 * sqrt(sqrt(1.0 / MSE)) - 0.63 + UM = 0.99 * sqrt(PNSR) - 5.28 + UM = 0.85 * sqrt(SDNSR) - 3.84 + UM = 9.14 * cor_sigma(cor_sigma(cor_sigma(SSIM))) + 0.30 + UM = 2.36 * cor_sigma(VIFP1) + 0.32 + UM = 0.0777 * SMALLFRY - 6.93 + UM = 1.53 * SHARPENBAD - 0.09 + UM = 4.14 * cor_sigma(cor_sigma(COR)) - 1.94 + UM = -0.055 * sqrt(sqrt(1.0 / NHW-N)) + 0.82 + UM = 1.43 * sqrt(sqrt(1.0 / NHW-C)) - 2.82 + UM = 1.03 * sqrt(sqrt(1.0 / NHW-R)) - 2.17 + cor_sigma(M) = 1.0 - sqrt(1.0 - M * M) .SH COPYRIGHT This is free and unencumbered software released into the public domain. diff --git a/src/metricsnhw.h b/src/metricsnhw.h index 7770c26..151ffd9 100644 --- a/src/metricsnhw.h +++ b/src/metricsnhw.h @@ -6,7 +6,7 @@ **************************************************************************** * Metrics NHW * * file: metricsnhw.h * -* version: 0.3.0 * +* version: 0.3.1 * * * **************************************************************************** ***************************************************************************/ @@ -18,7 +18,7 @@ #ifndef __METRICS_NHW__H #define __METRICS_NHW__H -#define METRICSNHW_VERSION "0.3.0" +#define METRICSNHW_VERSION "0.3.1" #ifdef METRICS_STATIC #define METRICSAPI static diff --git a/src/metricspsnr.h b/src/metricspsnr.h index 98f64db..0058052 100644 --- a/src/metricspsnr.h +++ b/src/metricspsnr.h @@ -2,7 +2,7 @@ **************************************************************************** * Metrics PSNR * * file: metricspsnr.h * -* version: 0.3.0 * +* version: 0.3.1 * * * **************************************************************************** ***************************************************************************/ @@ -14,7 +14,7 @@ #ifndef __METRICS_PSNR__H #define __METRICS_PSNR__H -#define METRICS_PSNR_VERSION "0.3.0" +#define METRICS_PSNR_VERSION "0.3.1" #ifdef METRICS_STATIC #define METRICSAPI static @@ -25,10 +25,9 @@ #ifdef __cplusplus extern "C" { #endif -METRICSAPI float metrics_mse(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels); -METRICSAPI float metrics_psnr(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels); -METRICSAPI float metrics_mse_cor(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels); -METRICSAPI float metrics_psnr_cor(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels); +METRICSAPI float metrics_mse(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels, int corel); +METRICSAPI float metrics_psnr(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels, int corel); +METRICSAPI float metrics_sdsnr(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels, int corel); #ifdef __cplusplus } #endif @@ -36,12 +35,99 @@ METRICSAPI float metrics_psnr_cor(unsigned char *ref, unsigned char *cmp, unsign #ifdef METRICS_PSNR_IMPLEMENTATION /* MSE(a,b) = 1/N * SUM(((a-b)/MAX)^2), MAX = 255 */ -METRICSAPI float metrics_mse(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels) +METRICSAPI float metrics_mse(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels, int corel) { - float error, suml, sum; - size_t k; + float im1, im2; + float sum1, sum2, sum1l, sum2l, suml, sum, error; + float sum12, sumq1, sumq2, q12, sum12l, sumq1l, sumq2l, sumq, cor; int y, x, d; + size_t k; + + sum1 = 0.0f; + sum2 = 0.0f; + sumq1 = 1.0f; + sumq2 = 1.0f; + // Correlation ref and cmp + if (corel) + { + k = 0; + sum1 = 0.0f; + sum2 = 0.0f; + for (y = 0; y < height; y++) + { + sum1l = 0.0f; + sum2l = 0.0f; + for (x = 0; x < width; x++) + { + for (d = 0; d < channels; d++) + { + im1 = (float)ref[k]; + im2 = (float)cmp[k]; + sum1l += im1; + sum2l += im2; + k++; + } + } + sum1 += sum1l; + sum2 += sum2l; + } + sum1 /= (float)k; + sum2 /= (float)k; + k = 0; + sum12 = 0.0f; + sumq1 = 0.0f; + sumq2 = 0.0f; + for (y = 0; y < height; y++) + { + sum12l = 0.0f; + sumq1l = 0.0f; + sumq2l = 0.0f; + for (x = 0; x < width; x++) + { + for (d = 0; d < channels; d++) + { + im1 = (float)ref[k]; + im1 -= sum1; + im2 = (float)cmp[k]; + im2 -= sum2; + q12 = (im1 * im2); + sum12l += q12; + sumq1l += (im1 * im1); + sumq2l += (im2 * im2); + k++; + } + } + sum12 += sum12l; + sumq1 += sumq1l; + sumq2 += sumq2l; + } + sumq = sqrt(sumq1 * sumq2); + if (sumq > 0.0f) + { + cor = sum12 / sumq; + } else { + cor = (sumq1 == sumq2) ? 1.0f : 0.0f; + } + cor = (cor < 0.0f) ? -cor : cor; + sumq1 /= k; + sumq2 /= k; + sumq1 = sqrt(sumq1); + sumq2 = sqrt(sumq2); + q12 = (sumq1 + sumq2); + if (q12 > 0.0f) + { + sumq1 *= (2.0f / q12); + sumq2 *= (2.0f / q12); + } + else + { + sumq1 = 1.0f; + sumq2 = 1.0f; + } + } + + // MSE k = 0; sum = 0.0f; for (y = 0; y < height; y++) @@ -51,7 +137,13 @@ METRICSAPI float metrics_mse(unsigned char *ref, unsigned char *cmp, unsigned ch { for (d = 0; d < channels; d++) { - error = (float)((ref[k] > cmp[k]) ? (ref[k] - cmp[k]) : (cmp[k] - ref[k])); + im1 = (float)ref[k]; + im1 -= sum1; + im1 *= sumq2; + im2 = (float)cmp[k]; + im2 -= sum2; + im2 *= sumq1; + error = (im1 > im2) ? (im1 - im2) : (im2 - im1); suml += error * error; if (delta) delta[k] = (unsigned char)error; k++; @@ -59,9 +151,7 @@ METRICSAPI float metrics_mse(unsigned char *ref, unsigned char *cmp, unsigned ch } sum += suml; } - sum /= (float)height; - sum /= (float)width; - sum /= (float)channels; + sum /= (float)k; sum /= 255.0f; sum /= 255.0f; @@ -69,14 +159,14 @@ METRICSAPI float metrics_mse(unsigned char *ref, unsigned char *cmp, unsigned ch } /* PSNR(a,b) = 10*log10(1 / MSE(a,b)) */ -METRICSAPI float metrics_psnr(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels) +METRICSAPI float metrics_psnr(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels, int corel) { int y, x, d; size_t k; float mse, psnr, t; - mse = metrics_mse(ref, cmp, delta, height, width, channels); - psnr = 10.0f * log10( 1.0f / mse); + mse = metrics_mse(ref, cmp, delta, height, width, channels, corel); + psnr = (mse > 0.0f) ? (10.0f * log10( 1.0f / mse)) : 0.0f; if (delta) { @@ -93,7 +183,7 @@ METRICSAPI float metrics_psnr(unsigned char *ref, unsigned char *cmp, unsigned c t += mse; t *= 0.5f; t = (t > 0.0f) ? (10.0f * log10( 1.0f / t)) : 255.0f; - delta[k] = (unsigned char)((t < 255.0f) ? t : 255); + delta[k] = (unsigned char)((t < 0.0f) ? 0.0f : (t < 255.0f) ? t : 255); k++; } } @@ -103,131 +193,58 @@ METRICSAPI float metrics_psnr(unsigned char *ref, unsigned char *cmp, unsigned c return psnr; } -METRICSAPI float metrics_mse_cor(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels) +/* SDSNR(a,b) = 10*log10((S2(a)+ S2(b)) / MSE(a,b) / 2) + * S2(a) = 1/N * (SUM((a/MAX)^2) - SUM(1/N * (a/MAX))^2) + * S2(b) = 1/N * (SUM((b/MAX)^2) - SUM(1/N * (b/MAX))^2) + * MSE(a,b) = 1/N * SUM(((a-b)/MAX)^2), MAX = 255 */ +float stdev2(unsigned char *ref, int height, int width, int channels) { - float im1, im2; - float sum1, sum2, sum1l, sum2l, suml, sum, error; - float sum12, sumq1, sumq2, q12, sum12l, sumq1l, sumq2l, sumq, cor; + float sum2l, sum2, suml, sum, val; + size_t k; int y, x, d; - size_t k, n; - - n = width * height; k = 0; - sum1 = 0.0f; sum2 = 0.0f; - for (y = 0; y < height; y++) - { - sum1l = 0.0f; - sum2l = 0.0f; - for (x = 0; x < width; x++) - { - for (d = 0; d < channels; d++) - { - im1 = (float)ref[k]; - im2 = (float)cmp[k]; - sum1l += im1; - sum2l += im2; - k++; - } - } - sum1 += sum1l; - sum2 += sum2l; - } - sum1 /= (float)k; - sum2 /= (float)k; - - k = 0; - sum12 = 0.0f; - sumq1 = 0.0f; - sumq2 = 0.0f; - for (y = 0; y < height; y++) - { - sum12l = 0.0f; - sumq1l = 0.0f; - sumq2l = 0.0f; - for (x = 0; x < width; x++) - { - for (d = 0; d < channels; d++) - { - im1 = (float)ref[k]; - im1 -= sum1; - im2 = (float)cmp[k]; - im2 -= sum2; - q12 = (im1 * im2); - sum12l += q12; - sumq1l += (im1 * im1); - sumq2l += (im2 * im2); - k++; - } - } - sum12 += sum12l; - sumq1 += sumq1l; - sumq2 += sumq2l; - } - sumq = sqrt(sumq1 * sumq2); - if (sumq > 0.0f) - { - cor = sum12 / sumq; - } else { - cor = (sumq1 == sumq2) ? 1.0f : 0.0f; - } - cor = (cor < 0.0f) ? -cor : cor; - sumq1 /= k; - sumq2 /= k; - sumq1 = sqrt(sumq1); - sumq2 = sqrt(sumq2); - q12 = (sumq1 + sumq2); - if (q12 > 0.0f) - { - sumq1 *= (2.0f / q12); - sumq2 *= (2.0f / q12); - } - else - { - sumq1 = 1.0f; - sumq2 = 1.0f; - } - k = 0; sum = 0.0f; for (y = 0; y < height; y++) { + sum2l = 0.0f; suml = 0.0f; for (x = 0; x < width; x++) { for (d = 0; d < channels; d++) { - im1 = (float)ref[k]; - im1 -= sum1; - im1 *= sumq2; - im2 = (float)cmp[k]; - im2 -= sum2; - im2 *= sumq1; - error = (im1 > im2) ? (im1 - im2) : (im2 - im1); - suml += error * error; - if (delta) delta[k] = (unsigned char)error; + val = (float)ref[k]; + sum2l += (val * val); + suml += val; k++; } } + sum2 += sum2l; sum += suml; } - sum /= (float)height; - sum /= (float)width; - sum /= (float)channels; - sum /= 255.0f; - sum /= 255.0f; + sum /= (float)k; + sum *= sum; + sum2 -= sum; + sum2 /= (float)k; - return sum; + return sum2; } -METRICSAPI float metrics_psnr_cor(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels) +METRICSAPI float metrics_sdsnr(unsigned char *ref, unsigned char *cmp, unsigned char* delta, int height, int width, int channels, int corel) { int y, x, d; size_t k; - float mse, psnr, t, sum1, sum2, sum1l, sum2l; + float s2a, s2b, s2, mse, sdsnr, t; + + s2a = stdev2(ref, height, width, channels); + s2b = stdev2(cmp, height, width, channels); + s2 = 0.5f * (s2a + s2b); + mse = metrics_mse(ref, cmp, delta, height, width, channels, corel); + mse *= 255.0f; + mse *= 255.0f; - mse = metrics_mse_cor(ref, cmp, delta, height, width, channels); - psnr = 10.0f * log10( 1.0f / mse); + sdsnr = (mse > 0.0f) ? (10.0f * log10(s2 / mse)) : 0.0f; if (delta) { @@ -239,19 +256,18 @@ METRICSAPI float metrics_psnr_cor(unsigned char *ref, unsigned char *cmp, unsign for (d = 0; d < channels; d++) { t = (float)delta[k]; - t /= 255.0f; t *= t; t += mse; t *= 0.5f; - t = (t > 0.0f) ? (10.0f * log10( 1.0f / t)) : 255.0f; - delta[k] = (unsigned char)((t < 255.0f) ? t : 255); + t = (t > 0.0f) ? (10.0f * log10(s2 / t)) : 255.0f; + delta[k] = (unsigned char)((t < 0.0f) ? 0.0f : (t < 255.0f) ? t : 255); k++; } } } } - return psnr; + return sdsnr; } #endif /* METRICS_PSNR_IMPLEMENTATION */ diff --git a/src/metricsum.h b/src/metricsum.h index b724871..55dd691 100644 --- a/src/metricsum.h +++ b/src/metricsum.h @@ -2,7 +2,7 @@ **************************************************************************** * Metrics UM * * file: metricsum.h * -* version: 0.3.0 * +* version: 0.3.1 * * * **************************************************************************** ***************************************************************************/ @@ -15,7 +15,7 @@ #ifndef __METRICS_UM__H #define __METRICS_UM__H -#define METRICS_VERSION "0.3.0" +#define METRICS_VERSION "0.3.1" #ifdef METRICS_STATIC #define METRICSAPI static @@ -55,57 +55,63 @@ float metricssigma(float cor) /* Universal scale of Metrics */ METRICSAPI float metric_um(char* metric, float value) { - if ((strcmp(metric, "mse") == 0) || (strcmp(metric, "mse-c") == 0)) + if (strcmp(metric, "mse") == 0) { if (value > 0.0f) { value = 1.0f / value; value = sqrt(value); value = sqrt(value); - value *= 0.148f; - value -= 0.53f; + value *= 0.158f; + value -= 0.63f; } else { value = 1.0f; } } - else if ((strcmp(metric, "psnr") == 0) || (strcmp(metric, "psnr-c") == 0)) + else if (strcmp(metric, "psnr") == 0) { value = sqrt(value); - value *= 0.94f; - value -= 4.94f; + value *= 0.99f; + value -= 5.28f; + } + else if (strcmp(metric, "sdsnr") == 0) + { + value = sqrt(value); + value *= 0.85f; + value -= 3.84f; } else if (strcmp(metric, "ssim") == 0) { value = metricssigma(value); value = metricssigma(value); value = metricssigma(value); - value *= 8.57f; - value += 0.34f; + value *= 9.14f; + value += 0.30f; } else if (strcmp(metric, "vifp1") == 0) { value = metricssigma(value); - value *= 2.21f; - value += 0.36f; + value *= 2.36f; + value += 0.32f; } else if (strcmp(metric, "smallfry") == 0) { - value *= 0.0735f; - value -= 6.50f; + value *= 0.0777f; + value -= 6.93f; } else if (strcmp(metric, "shbad") == 0) { - value *= 1.46f; - value -= 0.04f; + value *= 1.53f; + value -= 0.09f; } else if (strcmp(metric, "cor") == 0) { value = metricssigma(value); value = metricssigma(value); - value *= 3.92f; - value -= 1.79f; + value *= 4.14f; + value -= 1.94f; } else if (strcmp(metric, "nhw-c") == 0) { @@ -114,8 +120,8 @@ METRICSAPI float metric_um(char* metric, float value) value = 1.0f / value; value = sqrt(value); value = sqrt(value); - value *= 1.36f; - value -= 2.61f; + value *= 1.43f; + value -= 2.82f; } else { @@ -129,8 +135,8 @@ METRICSAPI float metric_um(char* metric, float value) value = 1.0f / value; value = sqrt(value); value = sqrt(value); - value *= -0.049f; - value += 0.83f; + value *= -0.055f; + value += 0.82f; } else { @@ -144,8 +150,8 @@ METRICSAPI float metric_um(char* metric, float value) value = 1.0f / value; value = sqrt(value); value = sqrt(value); - value *= 0.96f; - value -= 1.98f; + value *= 1.03f; + value -= 2.17f; } else { @@ -176,11 +182,15 @@ METRICSAPI float metric_um_image(unsigned char* delta, int height, int width, in { value = (float)delta[k]; value /= 255; - if ((strcmp(metric, "mse") == 0) || (strcmp(metric, "mse-c") == 0)) + if (strcmp(metric, "mse") == 0) { value *= value; } - else if ((strcmp(metric, "psnr") == 0) || (strcmp(metric, "psnr-c") == 0)) + else if (strcmp(metric, "psnr") == 0) + { + value *= 255.0f; + } + else if (strcmp(metric, "sdsnr") == 0) { value *= 255.0f; } diff --git a/src/smallfry.h b/src/smallfry.h index e958eda..8e9b2f5 100644 --- a/src/smallfry.h +++ b/src/smallfry.h @@ -18,7 +18,7 @@ **************************************************************************** * Metrics PSNR * * file: metricspsnr.h * -* version: 0.3.0 * +* version: 0.3.1 * * * **************************************************************************** ***************************************************************************/ @@ -31,7 +31,7 @@ #ifndef __METRICS_SMALLFRY__H #define __METRICS_SMALLFRY__H -#define METRICS_SMALLFRY_VERSION "0.3.0" +#define METRICS_SMALLFRY_VERSION "0.3.1" #ifdef METRICS_STATIC #define METRICSAPI static diff --git a/src/ssim.h b/src/ssim.h index 872bcb2..71980e1 100644 --- a/src/ssim.h +++ b/src/ssim.h @@ -6,7 +6,7 @@ **************************************************************************** * Metrics SSIM * * file: ssim.h * -* version: 0.3.0 * +* version: 0.3.1 * * * **************************************************************************** ***************************************************************************/ @@ -19,7 +19,7 @@ #ifndef SSIM_H_ #define SSIM_H_ -#define METRICS_SSIM_VERSION "0.3.0" +#define METRICS_SSIM_VERSION "0.3.1" #ifdef METRICS_STATIC #define METRICSAPI static diff --git a/src/stbimmetrics.c b/src/stbimmetrics.c index a68dac0..3407606 100644 --- a/src/stbimmetrics.c +++ b/src/stbimmetrics.c @@ -20,10 +20,10 @@ void immetrics_usage(char* prog, char* metric) printf("usage: %s [options] image_in_orig image_in_comp [metric_out.png]\n", prog); printf("options:\n"); printf("\t-m STR\tmetric (default %s):\n", metric); + printf("\t-c\tcorrelation mode: for MSE, PSNR, SDSNR\n"); printf("\t\tmse -\t MSE / MAX^2, MAX = 255\n"); printf("\t\tpsnr -\t PSNR\n"); - printf("\t\tmse-c -\t MSE / MAX^2 of correlation, MAX = 255\n"); - printf("\t\tpsnr-c -\t PSNR of correlation\n"); + printf("\t\tsdsnr -\t SDSNR\n"); printf("\t\tssim -\t SSIM\n"); printf("\t\tsmallfry -\t SMALLFRY\n"); printf("\t\tshbad -\t SHARPENBAD\n"); @@ -43,6 +43,7 @@ int main(int argc, char **argv) int height = 0, width = 0, channels = 0; int height_c = 0, width_c = 0, channels_c = 0; char *metric = "psnr"; + int corel = 0; int fhelp = 0; int fquiet = 0; int fum = 0; @@ -54,10 +55,13 @@ int main(int argc, char **argv) size_t ki = 0, kd = 0; float neatness = 0.0f; - while ((opt = getopt(argc, argv, ":m:quyh")) != -1) + while ((opt = getopt(argc, argv, ":cm:quyh")) != -1) { switch(opt) { + case 'c': + corel = 1; + break; case 'm': metric = optarg; break; @@ -187,19 +191,15 @@ int main(int argc, char **argv) { if (strcmp(metric, "mse") == 0) { - neatness = metrics_mse(data_orig, data_comp, data_m, height, width, channels); + neatness = metrics_mse(data_orig, data_comp, data_m, height, width, channels, corel); } else if (strcmp(metric, "psnr") == 0) { - neatness = metrics_psnr(data_orig, data_comp, data_m, height, width, channels); - } - else if (strcmp(metric, "mse-c") == 0) - { - neatness = metrics_mse_cor(data_orig, data_comp, data_m, height, width, channels); + neatness = metrics_psnr(data_orig, data_comp, data_m, height, width, channels, corel); } - else if (strcmp(metric, "psnr-c") == 0) + else if (strcmp(metric, "sdsnr") == 0) { - neatness = metrics_psnr_cor(data_orig, data_comp, data_m, height, width, channels); + neatness = metrics_sdsnr(data_orig, data_comp, data_m, height, width, channels, corel); } else if (strcmp(metric, "smallfry") == 0) { diff --git a/src/ycbcr.h b/src/ycbcr.h index ddc5a18..f2e61ce 100644 --- a/src/ycbcr.h +++ b/src/ycbcr.h @@ -2,7 +2,7 @@ **************************************************************************** * YCbCr Filter * * file: ycbcr.h * -* version: 0.3.0 * +* version: 0.3.1 * * * **************************************************************************** ***************************************************************************/ @@ -13,7 +13,7 @@ #ifndef __YCBCR__H #define __YCBCR__H -#define YCBCR_VERSION "0.3.0" +#define YCBCR_VERSION "0.3.1" #ifdef METRICS_STATIC #define METRICSAPI static