(C++) HistogramEqualization

February 24, 2017 · View on GitHub

 

 

 

 

 

(C++) VCL HistogramEqualization

 

HistogramEqualization is a VCL code snippet to perform a histogram equalization.

 

 


//From http://www.richelbilderbeek.nl/CppHistogramEqualization.htm void HistogramEqualization(const TImage * const source, TImage * const target) {   assert(source!=0 && "Source image is NULL");   assert(target!=0 && "Target image is NULL");   assert(source->Picture->Bitmap!=0 && "Source bitmap is NULL");   assert(target->Picture->Bitmap!=0 && "Target bitmap is NULL");   assert(source->Picture->Bitmap->PixelFormat == pf24bit && "Source bitmap must be 24 bit");   assert(target->Picture->Bitmap->PixelFormat == pf24bit && "Target bitmap must be 24 bit");   //Get the width and height from the source   const int width  = source->Picture->Bitmap->Width;   const int height = source->Picture->Bitmap->Height;   //Set the target's width and height   target->Picture->Bitmap->Width  = width;   target->Picture->Bitmap->Height = height;   const int surface = width * height;   const int nGreyValues = 256; //There are 256 different pixel intensities   const std::vector<int> histogram = GetImageHistogram(source);   assert(nGreyValues==static_cast<int>(histogram.size()));   const std::vector<int> cumulativeHistogram = GetCumulativeHistogram(histogram);   assert(nGreyValues==static_cast<int>(cumulativeHistogram.size()));   //Works, but anybody knows how to use std::for_each or std::transform for this?   std::vector<int> rescaledHistogram(nGreyValues,0);   for (int i=0; i!=nGreyValues; ++i)   {     //'surface + 1' to prevent that rescaledGreyValue == 256     const int rescaledGreyValue       = static_cast<int>(           static_cast<double>(nGreyValues)         * static_cast<double>(cumulativeHistogram[i])         / static_cast<double>(surface + 1) );     assert(rescaledGreyValue >= 0);     assert(rescaledGreyValue < 256);     rescaledHistogram[i] = rescaledGreyValue;   }   for (int y=0; y!=height; ++y)   {     const unsigned char * lineSource       = static_cast<const unsigned char *>(         source->Picture->Bitmap->ScanLine[y]);     unsigned char * lineTarget       = static_cast<unsigned char *>(         target->Picture->Bitmap->ScanLine[y]);     for (int x=0; x!=width; ++x)     {       const int greyOriginal         = (lineSource[x*3+0] + lineSource[x*3+1] + lineSource[x*3+2]) / 3;       assert(greyOriginal >=   0);       assert(greyOriginal  < 256);       const int greyNew = rescaledHistogram[greyOriginal];       assert(greyNew >= 0);       assert(greyNew  < 256);       lineTarget[x*3+0]=greyNew; //Blue       lineTarget[x*3+1]=greyNew; //Green       lineTarget[x*3+2]=greyNew; //Red     }   } } //------------------------------------------------------------ //From http://www.richelbilderbeek.nl/CppConvertToGrey.htm void ConvertToGrey(const TImage * const source, TImage * const target) {   assert(source!=0 && "Source image is NULL");   assert(target!=0 && "Target image is NULL");   assert(source->Picture->Bitmap!=0 && "Source bitmap is NULL");   assert(target->Picture->Bitmap!=0 && "Target bitmap is NULL");   assert(source->Picture->Bitmap->PixelFormat == pf24bit && "Source bitmap must be 24 bit");   assert(target->Picture->Bitmap->PixelFormat == pf24bit && "Target bitmap must be 24 bit");   //Get the width and height from the source   const int width  = source->Picture->Bitmap->Width;   const int height = source->Picture->Bitmap->Height;   //Set the target's width and height   target->Picture->Bitmap->Width  = width;   target->Picture->Bitmap->Height = height;   for (int y=0; y!=height; ++y)   {     const unsigned char * lineSource       = static_cast<const unsigned char *>(         source->Picture->Bitmap->ScanLine[y]);     unsigned char * lineTarget       = static_cast<unsigned char *>(         target->Picture->Bitmap->ScanLine[y]);     for (int x=0; x!=width; ++x)     {       const int grey         = (lineSource[x*3+0] + lineSource[x*3+1] + lineSource[x*3+2]) / 3;       assert(grey >= 0 && grey < 256);       lineTarget[x*3+0]=grey; //Blue       lineTarget[x*3+1]=grey; //Green       lineTarget[x*3+2]=grey; //Red     }   } } //------------------------------------------------------------ //From htpp://www.richelbilderbeek.nl/CppGetImageHistogram.htm const std::vector<int> GetImageHistogram(const TImage * const image) {   assert(image!=0 && "Image is NULL");   assert(image->Picture->Bitmap!=0 && "Image bitmap is 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;   std::vector<int> histogram(256,0); //There are 256 different color values   for (int y=0; y!=height; ++y)   {     const unsigned char * line       = static_cast<const unsigned char *>(         image->Picture->Bitmap->ScanLine[y]);     for (int x=0; x!=width; ++x)     {       const int grey         = (line[x*3+0] + line[x*3+1] + line[x*3+2]) / 3;       assert(grey >= 0 && grey < 256);       ++histogram[grey];     }   }   return histogram; } //------------------------------------------------------------ //From htpp://www.richelbilderbeek.nl/CppGetCumulativeHistogram.htm template <class T> const std::vector<T> GetCumulativeHistogram(const std::vector<T>& histogram) {   std::vector<T> v(histogram.begin(),histogram.end() );   const int size = v.size();   for (int i=1; i!=size; ++i)   {     v[i] += v[i-1];   }   return v; } //------------------------------------------------------------