Browse Source

MCI3D: added histogram equalization

Sven Sickert 11 years ago
parent
commit
e4dbb52742
2 changed files with 44 additions and 12 deletions
  1. 7 1
      core/image/MultiChannelImage3DT.h
  2. 37 11
      core/image/MultiChannelImage3DT.tcc

+ 7 - 1
core/image/MultiChannelImage3DT.h

@@ -4,6 +4,7 @@
 #include <core/image/MultiChannelImageAccess3D.h>
 #include <core/image/MultiChannelImageAccess3D.h>
 #include <core/image/ImageT.h>
 #include <core/image/ImageT.h>
 #include <core/image/MultiChannelImageT.h>
 #include <core/image/MultiChannelImageT.h>
+#include <core/image/Histogram.h>
 
 
 #include <vector>
 #include <vector>
 #include <fstream>
 #include <fstream>
@@ -157,8 +158,13 @@ public:
   /** calculate image statistics */
   /** calculate image statistics */
   void statistics( P & min, P & max, uint channel = 0 ) const;
   void statistics( P & min, P & max, uint channel = 0 ) const;
 
 
-  /** correct inhomogeneous illuminations (shading) between the image slices **/
+  /** correct inhomogeneous illuminations between the image slices
+   *  ! Deprecated, use 'equalizeHistogram' instead !
+   */
   void correctShading( uint channel = 0 ) const;
   void correctShading( uint channel = 0 ) const;
+
+  /** do a histogram equalization */
+  void equalizeHistogram( uint channel = 0 ) const;
   
   
   /** dump all data to RAW format: xsize, ysize, numChannels, <data> */
   /** dump all data to RAW format: xsize, ysize, numChannels, <data> */
   void store( std::string filename ) const;
   void store( std::string filename ) const;

+ 37 - 11
core/image/MultiChannelImage3DT.tcc

@@ -37,17 +37,10 @@ P & MultiChannelImage3DT<P>::operator() (int x, int y, int z, uint channel)
 }
 }
 
 
 template<class P>
 template<class P>
-MultiChannelImageT<P> MultiChannelImage3DT<P>::operator[] (uint c)
-{
-  // This was our first idea ... but it creates a real copy
-  // ImageT<P> tmp ( data[c], xsize, ysize, xsize*sizeof(P), GrayColorImageCommonImplementation::noAlignment );
-  // This is the correct version. The funny thing about this is that shallowCopy
-  // is not an enum parameter, but an instance of ShallowCopyMode, which is a class.
-  // This fancy trick was done in older to prevent automatic conversion between enum types
-  // as done implicitly by C++.
-  
+MultiChannelImageT<P> MultiChannelImage3DT<P>::operator[] (uint z)
+{
   MultiChannelImageT<P> img;
   MultiChannelImageT<P> img;
-  for( int z = 0; z < zsize; z++ )
+  for( int c = 0; c < numChannels; c++ )
   {
   {
     P * datatmp = data[c];
     P * datatmp = data[c];
     ImageT<P> tmp ( &datatmp[z*(xsize*ysize)], xsize, ysize, xsize*sizeof(P), GrayColorImageCommonImplementation::shallowCopy );
     ImageT<P> tmp ( &datatmp[z*(xsize*ysize)], xsize, ysize, xsize*sizeof(P), GrayColorImageCommonImplementation::shallowCopy );
@@ -352,6 +345,7 @@ void MultiChannelImage3DT<P>::correctShading( uint channel ) const
 {
 {
   assert( channel < numChannels );
   assert( channel < numChannels );
   
   
+  // some sort of correction trick hardly understandable :-)
   std::vector<double> meanVals;
   std::vector<double> meanVals;
   for( int z = 0; z < zsize; z++ )
   for( int z = 0; z < zsize; z++ )
   {
   {
@@ -365,10 +359,12 @@ void MultiChannelImage3DT<P>::correctShading( uint channel ) const
     }
     }
     sumVal /= (xsize*ysize);
     sumVal /= (xsize*ysize);
     meanVals.push_back( sumVal );
     meanVals.push_back( sumVal );
+
   }
   }
 
 
   P newMax = std::numeric_limits<P>::min();
   P newMax = std::numeric_limits<P>::min();
-  short int maxVal = 255;
+
+  const short int maxVal = 255;
   for ( int z = 0; z < zsize; z++ )
   for ( int z = 0; z < zsize; z++ )
   {
   {
     for ( int y = 0; y < ysize; y++ )
     for ( int y = 0; y < ysize; y++ )
@@ -390,6 +386,35 @@ void MultiChannelImage3DT<P>::correctShading( uint channel ) const
   }
   }
 }
 }
 
 
+template<class P>
+void MultiChannelImage3DT<P>::equalizeHistogram( uint channel ) const
+{
+  assert(channel < numChannels );
+
+  for( int z = 0; z < zsize; z++ )
+  {
+    NICE::Image img = getChannel(z, channel );
+    NICE::Histogram hist(img,0,255,256);
+
+    NICE::IntVector *histVec = NULL;
+    histVec = hist.cumulative();
+    for ( int i = 0; i < (int)histVec->size(); i++)
+    {
+      histVec->set(i, histVec->get(i) * 255 / (double)histVec->get(histVec->size()-1));
+    }
+
+    for ( int y = 0; y < ysize; y++ )
+    {
+      for ( int x = 0; x < xsize; x++ )
+      {
+        data [channel][x + y*xsize + z*xsize*ysize] = histVec->get( img.getPixel(x,y) );
+      }
+    }
+
+    delete histVec;
+  }
+}
+
 template<class P>
 template<class P>
 Image MultiChannelImage3DT<P>::getChannel( int z, uint channel ) const
 Image MultiChannelImage3DT<P>::getChannel( int z, uint channel ) const
 {
 {
@@ -407,6 +432,7 @@ ImageT<P> MultiChannelImage3DT<P>::getChannelT( int z, uint channel ) const
   assert( channel < numChannels );
   assert( channel < numChannels );
 
 
   NICE::ImageT<P> img;
   NICE::ImageT<P> img;
+  // TODO do not convert to grey since we are using a template class image
   convertToGrey( img, z, channel, false );
   convertToGrey( img, z, channel, false );
   
   
   P min, max;
   P min, max;