Introduction
Sometimes, we have a some vague color photo that is not clear. This can be fixed. In the image processing field, it's called histogram equalization. It is important that it can expand the histogram of the image. Then, your photos will be clear.
Background
Equipment Operation System: Microsoft Windows 7 Professional (64 bit) Development Utility: Microsoft Visual Studio 2010
Using the Code
double aryHistogramR[256] = {0};
double aryTransformR[256] = {0};
double dobSumR = 0.0f;
double aryHistogramG[256] = {0};
double aryTransformG[256] = {0};
double dobSumG = 0.0f;
double aryHistogramB[256] = {0};
double aryTransformB[256] = {0};
double dobSumB = 0.0f;
int iJ = 0;
int iK = 0;
memset ( aryHistogramR, 0x00, 256 * sizeof( double ) );
memset ( aryHistogramG, 0x00, 256 * sizeof( double ) );
memset ( aryHistogramB, 0x00, 256 * sizeof( double ) );
for ( int iY = 0; iY < imageA->DibInfo->bmiHeader.biHeight; iY++ )
{
for ( int iX = 0; iX < imageA->DibInfo->bmiHeader.biWidth; iX++ )
{
lIDXA = ( iX * 3 ) + ( iY * imageA->DibInfo->bmiHeader.biWidth * 3 );
byteRGB_BA = imageA->DibArry[lIDXA+0];
byteRGB_GA = imageA->DibArry[lIDXA+1];
byteRGB_RA = imageA->DibArry[lIDXA+2];
aryHistogramR[INT(byteRGB_RA)]++;
aryHistogramG[INT(byteRGB_GA)]++;
aryHistogramB[INT(byteRGB_BA)]++;
} } memset ( aryTransformR, 0x00, 256 * sizeof( double ) );
memset ( aryTransformG, 0x00, 256 * sizeof( double ) );
memset ( aryTransformB, 0x00, 256 * sizeof( double ) );
for ( iJ = 0; iJ <= 255; iJ++ )
{
dobSumR = 0.0f;
dobSumG = 0.0f;
dobSumB = 0.0f;
for ( iK = 0; iK <= iJ; iK++ )
{
dobSumR = dobSumR + aryHistogramR[iK];
dobSumG = dobSumG + aryHistogramG[iK];
dobSumB = dobSumB + aryHistogramB[iK];
aryTransformR[iJ] = ( 255.0 * dobSumR /
( imageA->DibInfo->bmiHeader.biWidth * imageA->DibInfo->bmiHeader.biHeight ));
aryTransformG[iJ] = ( 255.0 * dobSumG /
( imageA->DibInfo->bmiHeader.biWidth * imageA->DibInfo->bmiHeader.biHeight ));
aryTransformB[iJ] = ( 255.0 * dobSumB /
( imageA->DibInfo->bmiHeader.biWidth * imageA->DibInfo->bmiHeader.biHeight ));
} } for ( int iY = 0; iY < imageA->DibInfo->bmiHeader.biHeight; iY++ )
{
for ( int iX = 0; iX < imageA->DibInfo->bmiHeader.biWidth; iX++ )
{
lIDXA = ( iX * 3 ) + ( iY * imageA->DibInfo->bmiHeader.biWidth * 3 );
byteRGB_BA = imageA->DibArry[lIDXA+0];
byteRGB_GA = imageA->DibArry[lIDXA+1];
byteRGB_RA = imageA->DibArry[lIDXA+2];
imageB->DibArry[lIDXA+0] = aryTransformB[INT(byteRGB_BA)];
imageB->DibArry[lIDXA+1] = aryTransformG[INT(byteRGB_GA)];
imageB->DibArry[lIDXA+2] = aryTransformR[INT(byteRGB_RA)];
} }
Exception
- There is a notice, if your bit depth of bitmap file is not 24 bits, you should change your bitmap files to adapt this program, or you could rewrite this source code to fit your bitmap format.
- You have to install Microsoft SDK v7.1, because I include windowscodes.lib.
#pragma comment(lib, "windowscodecs.lib")
Reference
- [1] Gary Bradski and Adrian Kaehler, “Learning OpenCV: Computer Vision with the OpenCV Library,” O’REILLY, September 2008, ISBN:978-0-596-51613-0
Acknowledgement
Thank you (Microsoft Visual Studio 2010, Lenna Sjööblom) very much for this great development utility and beautiful photo.