(C++) EnhanceContrast

February 24, 2017 · View on GitHub

 

 

 

 

 

(C++) EnhanceContrast

 

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.

 

 


#include <cassert> #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   for (int y=0; y!=height; ++y)   {     const unsigned char * const line       = static_cast<const unsigned char *>(         image->Picture->Bitmap->ScanLine[y]);     for (int x=0; x!=width; ++x)     {       const double grey         = 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;       }       else if (diff > 0.0)       {         //pixel was lighter then average         const double newStretch = (255.9 - averageGreyness)  / diff;         if (newStretch < stretch) stretch = newStretch;       }     }   }   //Enhance the contrast   for (int y=0; y!=height; ++y)   {     unsigned char * const line       = static_cast<unsigned char *>(         image->Picture->Bitmap->ScanLine[y]);     for (int x=0; x!=width; ++x)     {       const double grey         = 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     }   } }