Go back to Richel Bilderbeek's homepage.
Go back to Richel Bilderbeek's C++ page.
Graphics code snippet to enhance the contrast of a VCL TImage.
EnhanceContrast is similar to DoHistogramEqualization, except that EnhanceContrast is 'milder': it tries to minimally change the average greyness (using GetAverageGreyness to first measure it).
EnhanceContrast assumes that you've already defined GetAverageGreyness.
View an example of a composition image demonstrating EnhanceContrast and DoHistogramEqualization: first, on the original (top-left), a DoFilterOperation was performed, resulting in the bottom-left image. On this result, both a DoHistogramEqualization (top-right) and EnhanceContrast (bottom-right) were performed on.
View the code of 'EnhanceContrast' in plain text.
#include <vcl.h>
//From http://www.richelbilderbeek.nl/CppEnhanceContrast.htm
void EnhanceContrast(const TImage * const image)
{
//Find lowest and highest value
assert(image!=0 && "image must not be NULL");
assert(image->Picture->Bitmap!=0 && "image bitmap must not be NULL");
assert(image->Picture->Bitmap->PixelFormat == pf24bit && "image bitmap must be 24 bit");
//Get the width and height from the source
const int width = image->Picture->Bitmap->Width;
const int height = image->Picture->Bitmap->Height;
const double averageGreyness = GetAverageGreyness(image);
double stretch = 1000.0; //Way too much for nearly all images
{
const unsigned char * const line
= static_cast<const unsigned char *>(
image->Picture->Bitmap->ScanLine[y]);
{
= static_cast<double>(line[x*3+0] + line[x*3+1] + line[x*3+2])
/ 3.0;
const double diff = grey - averageGreyness;
if (diff < 0.0)
{
//pixel was darker then average
const double newStretch = -averageGreyness / diff;
assert(newStretch >= 0.0);
if (newStretch < stretch) stretch = newStretch;
}
{
//pixel was lighter then average
const double newStretch = (255.9 - averageGreyness) / diff;
if (newStretch < stretch) stretch = newStretch;
}
}
}
//Enhance the contrast
{
= static_cast<unsigned char *>(
image->Picture->Bitmap->ScanLine[y]);
{
= static_cast<double>(line[x*3+0] + line[x*3+1] + line[x*3+2])
/ 3.0;
const double diff = grey - averageGreyness;
const double diffGreyNew = averageGreyness + (static_cast<double>(diff) * stretch);
const int newGrey = static_cast<int>(diffGreyNew);
assert(newGrey >= 0);
assert(newGrey < 256);
line[x*3+2] = newGrey; //Red
line[x*3+1] = newGrey; //Green
line[x*3+0] = newGrey; //Blue
}
}
}
Go back to Richel Bilderbeek's C++ page.
Go back to Richel Bilderbeek's homepage.