/** * Define video types according to the size. */ public static enum videoType { //----- 176 * 144 QCIF, //----- QCIF * 2 = 352 * 288 CIF, //----- CIF * 2 = 704 * 576 FCIF } /** * Convert MSE to PSNR. * @param MSE * @param max the maximum value for each pixel * @return */ public static double videoMSEtoPSNR(double MSE, double max) { return 10 * Math.log10((max * max) / MSE); } /** * Calculate MSE for all components. * @param original the original image/video * @param result the other image/video that is compared to original one * @return */ public static double videoCalcMSE(byte[] original, byte[] result) { long sum = 0; int diff; for (int i = 0; i < original.length; i++) { int ioriginal = original[i] & 0xFF; int iresult = result[i] & 0xFF; diff = ioriginal - iresult; sum += diff * diff; } double MSE = sum / original.length; return MSE; } /** * Calculate PSNR for all components. * @param original the original image/video * @param result the other image/video that is compared to original one * @return */ public static double videoCalcPSNR(byte[] original, byte[] result) { double MSE = videoCalcMSE(original, result); double PSNR = videoMSEtoPSNR(MSE, 255.0); return PSNR; } /** * Calculate MSE only for Y component. * @param original the original image/video * @param result the other image/video that is compared to original one * @param type the size of image or video frame * @return */ public static double videoCalcMSEY(byte[] original, byte[] result, videoType type) { //----- decide the width and height according to the video type int width = 176; int height = 144; if (type == videoType.CIF) { width *= 2; height *= 2; } if (type == videoType.FCIF) { width *= 4; height *= 4; } //----- calculate the sum of diff^2 double sum = 0; int diff; int y_size = width * height; int frame_size = (int) (y_size * 1.5); //----- consider if the length of original and result is different int length = Math.min(original.length, result.length); if (length == 0) { printErr("the length of data is zero : calcMSE_y_general"); return -1; } for (int i = 0; i < length; i++) { if (i % frame_size < y_size) { int ioriginal = original[i] & 0xFF; int iresult = result[i] & 0xFF; diff = ioriginal - iresult; sum += diff * diff; } } //----- calculate the MSE and PSNR double MSE = sum / (original.length * 2.0 / 3.0); return MSE; } /** * Calculate the PSNR only for Y component. * @param original the original image/video * @param result the other image/video that is compared to original one * @param type the size of image or video frame * @return */ public static double videoCalcPSNRY(byte[] original, byte[] result, videoType type) { //----- calculate the MSE and PSNR double MSE = videoCalcMSEY(original, result, type); //----- the maximum value on each pixel is "255" double PSNR = videoMSEtoPSNR(MSE, 255.0); return PSNR; }