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);
}

Contact Us

*

*

Captcha Image

Why Choose Us

Wide Portfolio of Services


Domain Intensive Value Proposition


Technological Excellence across platforms 


Avail competitive pricing (Reduce 70% cost, ensure 100% quality)


Get 4 weeks complimentary Risk-Free Trial*


We Build Innovative Applications: Browse through our Intellectual Property

Client Testimonial

StartQuotes"Mindfire has enabled us to reduce costs and increase productivity. The team we have provides fast and reliable development support. We are very happy with the level of service from Mindfire." - Ken Morency, IceFire Studios Corp.

More Client Testimonials

News & Updates

  • December 18

    Third Edition: Tech Bhubaneswar

  • July 18

    Participation in Test Autothon, DSTC 2018

Let us Connect!

Awards and Achievements

Red Herringcolor DeloitteFast50 DB ZInnov1   Nascome  DB Stpi

This site uses cookies. We respect your privacy.copyright (c) Mindfire Solutions 2007-2018. Login