Image processing of image enhancement based on histogram equalization
Image histogram
The image histogram is an image statistics chart with 0-255 as the abscissa and the number of times the corresponding pixel value in the figure appears as the ordinate. The image histogram can be used to see the statistics of the image more intuitively
Histogram equalization
The histogram equalization is
calculated according to the transformation function . It can be understood that the grayscale density in any interval is equal to the grayscale interval divided by the total grayscale level, then the grayscale distribution is balanced.
Reference Code
void HistogramEqualize(BYTE *pImg, int width, int height)
{
BYTE *pCur, *pEnd = pImg+width*height;
unsigned int hist[256];
int LUT[256], i, sum;
// step.1---Hist---------------------//
memset(hist, 0, sizeof(int)*256);
for (pCur = pImg; pCur<pEnd;) hist[*(pCur++)]++;
// step.2---A[g]--------------------//
int A[256];
int g;
for (g = 0; g<256; g++)
{
sum = 0;
for (i = 0; i<=g; i++)
{
sum += hist[i];
}
A[g] = sum;
}
// step.3---N-----------------------//
int N = 0;
for (g = 0; g<256; g++)
{
if (hist[g]) N++;
}
//N=100;
int A0 = A[255];
// step.4---LUT---------------------//
for (g = 0; g<256; g++)
{
LUT[g]=N*A[g]/A0;
}
// step.5---F-----------------------//
for (pCur = pImg; pCur<pEnd;) *(pCur++) = LUT[*pCur];
// step.6---return------------------//
return;
}
Of course the code can be optimized
void HistogramEqualize(BYTE *pImg, int width, int height)
{
BYTE *pCur, *pEnd = pImg+width*height;
unsigned int hist[256];
int LUT[256];
// step.1---Hist---------------------//
memset(hist, 0, sizeof(int)*256);
for (pCur = pImg; pCur<pEnd;) hist[*(pCur++)]++;
// step.2---A[g]--------------------//
int A[256];
int g;
for (g = 1,A[0]=hist[0]; g<256; g++)
{
A[g] = A[g-1]+hist[g];
}
int A0 = A[255];
// step.4---LUT---------------------//
for (g = 0; g<256; g++)
{
LUT[g] = 255*A[g]/A0;
}
// step.5---F-----------------------//
for (pCur = pImg; pCur<pEnd;) *(pCur++) = LUT[*pCur];
// step.6---return------------------//
return;
}
Of course the code can be optimized
void RmwHistogramEqualize(BYTE *pImg, int width, int height)
{
BYTE *pCur, *pEnd = pImg+width*height;
unsigned int hist[256];
int LUT[256], g, A;
memset(hist, 0, sizeof(int)*256);
for (pCur = pImg; pCur<pEnd;) hist[*(pCur++)]++;
//LUT[0] = 255*hist[0]/(width*height);
//for (g = 1, A = hist[0], LUT[0]=0; g<256; g++)
for (g = 1, A = hist[0]; g<256; g++)
{
A = A+hist[g];
LUT[g] = 255*A/(width*height);
}
for (pCur = pImg; pCur<pEnd;) *(pCur++) = LUT[*pCur];
}
Experimental results