We take pride in your success. We let our positivity drive us, day in and out. Talk to us at Mindfire to know us more.

Standard Deviation between 32-bit and 24-bit bitmaps


Standard Deviation:

    It is common to find comparison of two bitmaps in Image Processing Development. Comparison of two bitmaps means how each pixel of image1 is different from corresponding pixel of image2 and vice-versa. This is called Standard Deviation. Standard Deviation tells us how many pixels are different in terms of its color in the given two images.

    Many software are available on Internet to calculate Standard Deviation, Photoshop is one of them. But we don't need to install any software,it can be done programmatically using the simple,generic and dynamic algorithm given below, in an Windows Console.

Key points of Algorithm:

    - It computes the Standard Deviation by calculating the difference of each channel (R,G,B and A) of a pixel.

    - The below algorithm is tested with the Photoshop based Standard Deviation. Results are 95% matching.

Note:


    The below algorithm is written for .bmp files only. So it supports only .bmp files.

Build Guide:

    - Create a Windows Console application project in Microsoft Visual Studio 2003/2005.

    - Project will be created with stdafx.h and main.cpp files.

    - Copy the below stdafx.h code into the stdafx.h file        

    - Copy the below StdDev.cpp code into the main.cpp file

    - Copy the bitmap files in where your   .vcproj  is created

    - Open Project properties and then go Configuration Properties  ---> Debugging ---> Command Arguments

    - Write the names of the bitmap files with a space. For example...

        TestFile1.bmp TestFile2.bmp

    - Build the project and Run the project.

    - Results will be displayed on the Console.

stdafx.h

    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>
    #include "stdlib.h"
    #include "malloc.h"
    #include "math.h"
    #include "string.h"
    #include "conio.h"

StdDev.cpp

#include "stdafx.h"

float StdDev24Bit(unsigned char* img1, unsigned char* img2, int width, int height)
{
    if ( !img1 || !img2 || !width || !height )
        return -1.0f;

    int        index = 0;
    float    sum    = 0;

    for( int y = 0; y < height; ++y )
    {
        for( int x = 0; x < width; ++x )
        {
            index = y * width + x;

            sum  +=    pow( float(img1[index+0] - img2[index+0]) , int(2)) +   
                    pow( float(img1[index+1] - img2[index+1]) , int(2)) +   
                    pow( float(img1[index+2] - img2[index+2]) , int(2)) ;   
        }
    }

    // std dev
    long pixels = width*height*3;
    float stdDev = sqrt(float(sum/pixels));
    return stdDev;
}



float StdDev32Bit(unsigned char* img1, unsigned char* img2, int width, int height)
{
    if ( !img1 || !img2 || !width || !height )
        return -1.0f;

    int        index = 0;
    float    sum    = 0;

    for( int y = 0; y < height; ++y )
    {
        for( int x = 0; x < width; ++x )
        {
            index = y * width + x;

            sum  +=    pow( float(img1[index+0] - img2[index+0]) , int(2)) +   
                    pow( float(img1[index+1] - img2[index+1]) , int(2)) +   
                    pow( float(img1[index+2] - img2[index+2]) , int(2)) +   
                    pow( float(img1[index+3] - img2[index+3]) , int(2)) ;   
        }
    }

    // std dev
    long pixels = width*height*4;
    float stdDev = sqrt(float(sum/pixels));
    return stdDev;
}


int main(int argc, char* argv[])
{
    if ( argc < 2 )
        return 0;    

    char drive[ _MAX_DRIVE ];
    char dir[ _MAX_DIR ];
    char fname1[_MAX_PATH] = {0};
    char fname2[_MAX_PATH] = {0};    
    char ext1[_MAX_EXT];
    char ext2[_MAX_EXT];
    char fname[ _MAX_FNAME ];
    char ext[ _MAX_EXT ];

    _splitpath( argv[0], drive, dir, fname, ext );
    if ( argv[1] == NULL || argv[2] == NULL )
    {
        printf("\n\nOne of the input image file is missing.\n\n");
        printf("Press ENTER to exit...");
        getch();
    }

    _splitpath(argv[1], drive, dir, fname1, ext1);
    _splitpath(argv[2], drive, dir, fname2, ext2);

    bool isBMPImages = false;
    if (_stricmp(".bmp", ext1)==0 && strcmp(".bmp", ext2)==0)
        isBMPImages = true;

    if (isBMPImages == false)
        return 0;

    // image1
    FILE* fp1 = fopen(argv[1], "rb");    
    if ( !fp1 )
    {
        printf("\n\nOne of the input image file is missing.\n\n");
        printf("Press ENTER to exit...");
        getch();
        return 0;
    }

    // Read image1 header
    BITMAPFILEHEADER bmf1;
    fread(&bmf1, sizeof(bmf1), 1, fp1);

    // Read image1 info header
    BITMAPINFOHEADER bmi1;
    fread(&bmi1, sizeof(bmi1), 1, fp1);

    // image2
    FILE* fp2 = fopen(argv[2], "rb");    
    if ( !fp2 )
    {
        fclose(fp1);
        printf("\n\nOne of the input image file is missing.\n\n");
        printf("Press ENTER to exit...");
        getch();
        return 0;
    }

    // Read image2 header
    BITMAPFILEHEADER bmf2;
    fread(&bmf2, sizeof(bmf2), 1, fp2);

    // Read image2 info header
    BITMAPINFOHEADER bmi2;
    fread(&bmi2, sizeof(bmi2), 1, fp2);

    if ( bmi1.biHeight != bmi2.biHeight || bmi1.biWidth != bmi2.biWidth)
    {
        printf("\n\nWidth and Height of given bitmaps are not matching.\n\n");
        fclose(fp1);
        fclose(fp2);
        return 0;
    }

    if (bmi1.biBitCount != bmi2.biBitCount)
    {
        fclose(fp1);
        fclose(fp2);
        printf("\n\nBitDepth of given bitmaps are not matching.n\n");
        printf("\n\nPress ENTER to exit...\n\n");
        getch();
        return 0;
    }

    int imgSize = bmi1.biHeight * bmi1.biWidth * (bmi1.biBitCount / 8);

    // read image1
    unsigned char *img1 = (unsigned char*)malloc(imgSize);
    if(!img1)
    {
        fclose(fp1);
        fclose(fp2);
        printf("\n\nmemory allocation problem\n\n");
        printf("\n\nPress ENTER to exit...\n\n");
        getch();
        return 0;
    }
    fread( img1, imgSize, 1, fp1);

    // read image2
    unsigned char *img2 = (unsigned char*)malloc(imgSize);
    if(!img2)
    {
        free(img1);
        fclose(fp1);
        fclose(fp2);
        printf("\n\nmemory allocation problem\n\n");
        printf("\n\nPress ENTER to exit...\n\n");
        getch();
        return 0;
    }
    fread( img2, imgSize, 1, fp2);

    // close files
    fclose(fp1);
    fclose(fp2);

    // calculate std dev
    float stdDev = -1;
    
    if (bmi1.biBitCount == 32)
        stdDev = StdDev32Bit(img1, img2, bmi1.biWidth, bmi1.biHeight);
    else if (bmi1.biBitCount == 24)
        stdDev = StdDev24Bit(img1, img2, bmi1.biWidth, bmi1.biHeight);    

    free(img1); img1 = NULL;
    free(img2); img2 = NULL;

    printf("\n\nStandard Deviation for %s and %s is: %2f \n\n", argv[1], argv[2],  stdDev);    
    printf("\n\nPress ENTER to exit...\n\n");
    getch();
    exit(0);
}

top

News & Updates

  • May 12

    We are attending Servoy World Conference'2012 at Amsterdam

  • April 12

    Mindfire attends Bug deBug conference & to attend Step Auto conference

Let us Connect!

privacy

copyright (c) Mindfire Solutions 2007-2012. Login