Peak Signal to Noise Ratio (PSNR) in decibels

 

PSNR is generally used to analyze quality of image, sound and video files in dB (decibels). PSNR calculation of two images, one original and an altered image, describes how far two images are equal. Figure 1 shows the famous formula.
 

                   MSE: Mean-Square error.
                         x: width of image.
                         y: height.
                      x*y: number of pixels (or quantities).


Figure 1. PSNR formula.

 

PSNR of Matrices in C

 

/*

 *   Give a reference to this site if you like to use this code.

 *
 *                               Written by Chasan Chouse, 2004

 */

double PSNR_Matrix( UCHAR **img1_data, // changed image
                    UCHAR **img2_data, // original image
                    long width,
                    long height)
{
    long i, j;
    double error, pix, x, psnr;

    /* calculating distortion */
    error = 0.0;
    pix = (double)width*(double)height;
    for(i=0;i<height;i++)
    {
        for(j=0;j<width;j++)
        {
            x = (double)img1_data[i][j] - (double)img2_data[i][j];
            error += ((x * x) / pix);
        }
    }
    psnr = 10.0 * log10((255.0*255.0)/error);

    return (psnr);
}
 

PSNR of Any Two Same Sized File

/***************************************/
/*  FILE SIZE OF A GIVEN STREAM        */
/***************************************/
long filesize(FILE *stream)
{
   long curpos, length;

   curpos = ftell(stream);
   fseek(stream, 0L, SEEK_END);
   length = ftell(stream);
   fseek(stream, curpos, SEEK_SET);
   return length;
}

double PSNR_AnyFile(char FileName1[], // changed image
                    char FileName2[]) // original image
{
    long i, j, sz;
    double error, pix, x, psnr;
    FILE *f1, *f2;

    f1 = fopen(FileName1, "rb");
    f2 = fopen(FileName2, "rb");
    if ( ( sz = filesize(f1)) != filesize(f2))
    {
        DispError("Size of two files must be equal");
        fclose(f1);
        fclose(f2);
        return 0;
    }
    /* calculating distortion */
    error = 0.0;
    for(i=0;i<sz;i++)
    {
        x = (double)fgetc(f1) - (double)fgetc(f2);
        error += ((x * x) / sz);
    }
    psnr = 10.0 * log10((255.0*255.0)/error);

    fclose(f1);
    fclose(f2);
    return (psnr);
}

 

Copyright by Chasan Chouse