Browse Source

merged branches

Johannes Ruehle 11 years ago
parent
commit
bc860d6398

+ 1 - 0
Doxyfile

@@ -622,6 +622,7 @@ FILE_PATTERNS          = *.doxy \
 *.cxx \
 *.cpp \
 *.c++ \
+*.tcc \
 *.d \
 *.java \
 *.ii \

+ 2 - 1
Makefile

@@ -258,7 +258,8 @@ moc_%.cpp:%.h
 $(BUILDDIR)%.a:
 	@$(MKOUTPUTDIR)
 	$(VERBOSE)echo "+++ linking library $@"
-	$(VERBOSE2)$(AR) cr $@ $(filter %.o,$^)
+	$(VERBOSE2)test -n "$(filter %.o,$^)" && $(AR) -crs $@ $(filter %.o,$^); echo;
+	$(VERBOSE2)test -f "$@" || (touch emptysource.cpp; gcc -c emptysource.cpp; $(AR) -crs $@ emptysource.o; rm emptysource.*); echo
 	@touch $@
 	@$(call MKOUTPUTDIR2,$(LIBSYMLINKDIR))
 	$(VERBOSE2)cd $(LIBSYMLINKDIR);$(SYMLINK) ../$(@:$(BUILDDIR)%=%) $(@F)

+ 15 - 12
core/basics/Config.cpp

@@ -1,11 +1,12 @@
+// STL includes
 #include <assert.h>
-
 #include <fstream>
 
-#include "Config.h"
-#include "ossettings.h"
-
-#include "StringTools.h"
+// nice-core includes
+#include "core/basics/Exception.h"
+#include "core/basics/Config.h"
+#include "core/basics/ossettings.h"
+#include "core/basics/StringTools.h"
 
 using namespace NICE;
   
@@ -335,13 +336,15 @@ std::string Config::gS(const std::string & key) const
 std::string Config::gS(const std::string & block, const std::string & key) const
 {
     std::string v ("");
-    if ( confS.find(block, key, v) ) {
-		return v;
-    } else {
-		fprintf (stderr, "Config: setting %s::%s not found !\n", block.c_str(), key.c_str() );
-		fprintf (stderr, "Config: %s\n", help(block, key).c_str() );
-		exit(-1);
-		return ""; // never reached
+    if ( confS.find(block, key, v) )
+    {
+      return v;
+    }
+    else
+    {
+      std::string errorMessage = "Config: setting " + block + "::" + key + " not found !\n";
+      errorMessage += "\n \n Config: " + help(block, key) + "\n";
+      throw NICE::Exception( errorMessage );
     }
 
 }

+ 13 - 0
core/basics/numerictools.cpp

@@ -5,14 +5,20 @@
  */
 #include "core/basics/numerictools.h"
 
+// STL includes
 #include <errno.h>
 #include <sstream>
+#include <iomanip>
 #include <clocale>
+
+// NICE-core includes
 #include <core/basics/Log.h>
 #include <core/basics/Timer.h>
 #include <core/basics/Exception.h>
 #include <core/basics/Streamable.h>
 
+typedef unsigned int uint;
+
 namespace NICE {
 
 // check if endptr is empty string (except for whitespaces)
@@ -80,6 +86,13 @@ std::string intToString(const int i) {
   return s.str();
 }
 
+std::string intToString(const int i, const uint & length) {
+  std::stringstream s;
+  s << std::setw( length ) << std::setfill('0') << i;
+  return s.str();
+}
+
+
 std::string doubleToString(const double d, const unsigned int digits,
                            const bool fixedPoint) {
   std::stringstream s;

+ 43 - 7
core/basics/numerictools.h

@@ -8,13 +8,13 @@
 #define _USE_MATH_DEFINES
 #include <cmath>
 #ifdef WIN32
-	#include <math.h>
+#   include <math.h>
 #endif
 
 #include "CrossplatformDefines.h"
 
 #ifdef NICE_BOOST_FOUND
-#include <boost/math/special_functions/fpclassify.hpp> // isnan
+#   include <boost/math/special_functions/fpclassify.hpp> // isnan
 #endif
 
 #include <stdlib.h>
@@ -212,13 +212,11 @@ inline double cubeRoot(const double& t) {
  * Check if a floating point value is NaN
  */
 inline bool isNaN(double x) {
-	
-
 #ifdef NICE_BOOST_FOUND
 	return  boost::math::isnan(x);
 #else
 	#if (__GNUC__ > 3)
-	  return isnan(x);
+	  return std::isnan(x);
 	#else
 	  return x != x;
 	#endif
@@ -233,7 +231,7 @@ inline bool isNaN(float x) {
 	return  boost::math::isnan(x);
 #else
 	#if (__GNUC__ > 3)
-	  return isnan(x);
+	  return std::isnan(x);
 	#else
 	  return x != x;
 	#endif
@@ -248,6 +246,8 @@ inline bool isFinite(double x)
 	#else
 		NICE_ERROR("isFinite() not defined (and neither is boost found for compensation...)")
 	#endif
+#if (__GNUC__ > 3)
+  return std::isnan(x);
 #else
 	return finite(x);
 #endif
@@ -433,10 +433,21 @@ inline long stringToInt(std::string s) {
 }
 
 /**
- * Convert an integer into a string.
+ * @brief Convert an integer into a string
  */
 std::string intToString(const int i);
 
+/**
+ * @brief Convert an integer into a string of fixed length, add leading zeros if needed.
+ * @author Alxander Freytag
+ * @date 13-01-2014 (dd-mm-yyyy)
+ * 
+ * @param i - number to convert
+ * @param length - resulting length of string including leading zeros
+ * @return string
+ */
+std::string intToString(const int i, const uint & length);
+
 /**
  * Convert a double into a string.
  */
@@ -457,6 +468,31 @@ inline int roundInt(float d) {
   return int(roundf(d));
 }
 
+
+/**
+ * @brief Compute number of digits (including sign) of a given number w.r.t. a specified base (ONLY USEFUL FOR INT-LIKE VARIABLES)
+ * @author Alexander Freytag
+ * @date 13-01-2014 (dd-mm-yyyy)
+ *
+ * @param number 
+ * @param base  ( default is 10).
+ * @return int
+ **/
+template <class T>
+int getNumDigits(T number, T base = 10 )
+{
+    int digits ( 0 );
+    
+    // note: only possible, because we call it using call-by-value!
+    while ( number )
+    {
+        number /= base;
+        digits++;
+    }
+    
+    return digits;
+}
+
 } // namespace
 
 #endif // _NUMERICTOOLS_FBASICS_H

+ 2 - 0
core/basics/tools.cpp

@@ -5,6 +5,8 @@
  */
 #include <core/basics/tools.h>
 
+typedef unsigned int uint;
+
 namespace NICE {
 
 void writeLatexTabular(std::ostream& out,

+ 79 - 43
core/image/ImageFile.cpp

@@ -136,52 +136,88 @@ void ImageFile::readerPNG(GrayColorImageCommonImplementationT<Ipp32f> *image)
 	
     }
 
-    template<>
-    void ImageFile::writerMagick(const GrayColorImageCommonImplementationT<unsigned char> *image) const
+template<>
+void ImageFile::writerMagick(const GrayColorImageCommonImplementationT<unsigned char> *image) const
+{
+  if ( image->channels() == 1 ) // gray image
+  {
+      Magick::Image magick_image;
+    // checking whether we have not a simple aligned image (block in memory)
+    if ( image->rowStepsize() != image->width() )
     {
-	if ( image->channels() == 1 ) {
-	    Magick::Image magick_image;
-		// checking whether we have not a simple aligned image (block in memory)
-		if ( image->rowStepsize() != image->width() ) {
-			// this means that we have a sub image or an IPP image
-			// (i.e. some pixels are skipped in each row)
-			// The Blob interface of ImageMagick is not flexible enough to handle this case
-			//
-			// Solution: we have to copy the image :(
-			// We do this by creating an empty NICE image
-			ImageT<unsigned char> image_noalignment;
-			// Setting the memory alignment and copying from image
-			image_noalignment.copyFrom ( *image, GrayColorImageCommonImplementation::noAlignment );
-			// and doing the conversion to a Magick image
-			// the alternative would be to directly copy from image to magick_image without memory
-			// operations, but this could be slower
-			Magick::Blob blob ( image_noalignment.getPixelPointer(), image_noalignment.width()*image_noalignment.height() );
-	    	magick_image.magick ("GRAY");
+      // this means that we have a sub image or an IPP image
+      // (i.e. some pixels are skipped in each row)
+      // The Blob interface of ImageMagick is not flexible enough to handle this case
+      //
+      // Solution: we have to copy the image :(
+      // We do this by creating an empty NICE image
+      ImageT<unsigned char> image_noalignment;
+      // Setting the memory alignment and copying from image
+      image_noalignment.copyFrom ( *image, GrayColorImageCommonImplementation::noAlignment );
+      // and doing the conversion to a Magick image
+      // the alternative would be to directly copy from image to magick_image without memory
+      // operations, but this could be slower
+      Magick::Blob blob ( image_noalignment.getPixelPointer(), image_noalignment.width()*image_noalignment.height() );
+        magick_image.magick ("GRAY");
             magick_image.read ( blob, Magick::Geometry ( image_noalignment.width(), image_noalignment.height() ), 8 );
-	    	magick_image.write ( filename );
-		} else {
-        	Magick::Blob blob ( image->getPixelPointer(), image->width()*image->height() );
-	    	magick_image.magick ("GRAY");
-            magick_image.read ( blob, Magick::Geometry ( image->width(), image->height() ), 8 );
-	    	magick_image.write ( filename );
-		}
-	} else {
-		// see above, the same problems occur for RGB images
-		if ( image->rowStepsize() != image->width() ) {
-			ColorImageT<unsigned char> image_noalignment;
-			image_noalignment.copyFrom ( *image, GrayColorImageCommonImplementation::noAlignment );
-			Magick::Image magick_image ( image_noalignment.width(), image_noalignment.height(),
-				"RGB", Magick::CharPixel, image_noalignment.getPixelPointer() );
-	    	magick_image.write ( filename );
-
-		} else {
-			// we do not need the Blob definition here (somehow strange)
-		    Magick::Image magick_image ( image->width(), image->height(),
-				"RGB", Magick::CharPixel, image->getPixelPointer() );
-	    	magick_image.write ( filename );
-		}
-	}
+        magick_image.write ( filename );
+    }
+    else
+    {
+        Magick::Blob blob ( image->getPixelPointer(), image->width()*image->height() );
+        
+        magick_image.magick ("GRAY");
+        magick_image.read ( blob, Magick::Geometry ( image->width(), image->height() ), 8 );
+        
+        magick_image.write ( filename );
     }
+  }
+  else // color image
+  {
+    // see above, the same problems occur for RGB images
+    if ( image->rowStepsize() != image->width() )
+    {
+      ColorImageT<unsigned char> image_noalignment;
+      
+      image_noalignment.copyFrom ( *image, GrayColorImageCommonImplementation::noAlignment );
+      Magick::Image magick_image ( image_noalignment.width(), image_noalignment.height(),
+        "RGB", Magick::CharPixel, image_noalignment.getPixelPointer() );
+      
+      std::string pngEnding ( ".png" );
+      // do we currently want to write a png file?
+      // if so, adapt writing parameters accordingly 
+      //
+      // needed for compatibility with png writer
+      if ( filename.compare( filename.length() - pngEnding.length(), pngEnding.length(), pngEnding) == 0)
+      {
+        magick_image.defineValue( "png", "bit-depth", "8");
+        magick_image.defineValue( "png", "format", "png8");
+      }
+      
+      magick_image.write ( filename );
+
+    }
+    else
+    {
+      // we do not need the Blob definition here (somehow strange)
+      Magick::Image magick_image ( image->width(), image->height(),
+      "RGB", Magick::CharPixel, image->getPixelPointer() );
+        
+      std::string pngEnding ( ".png" );
+      // do we currently want to write a png file?
+      // if so, adapt writing parameters accordingly 
+      //
+      // needed for compatibility with png writer
+      if ( filename.compare( filename.length() - pngEnding.length(), pngEnding.length(), pngEnding) == 0)
+      {
+        magick_image.defineValue( "png", "bit-depth", "8");
+        magick_image.defineValue( "png", "format", "png8");
+      }
+      
+      magick_image.write ( filename );
+    }
+  }
+}
 #endif
 
 ImageFile::Format ImageFile::name2Format(const std::string &filename)

+ 8 - 2
core/image/ImageFile.h

@@ -4,8 +4,10 @@
  * See file License for license information.
  */
 /*****************************************************************************/
-/*! \file ImageFile.h 
-    \brief ImageFile class declaration
+/** @file ImageFile.h 
+    @brief ImageFile class declaration
+    @author Michael Koch, Erik Rodner, Alexander Freytag
+    @date 22-01-2014 (dd-mm-yyyy)
  */
 /*****************************************************************************/
 /*
@@ -230,6 +232,10 @@ class ImageFile
 /*****************************************************************************/
 /*
  *  $Log: ImageFile.h,v $
+ * 
+ *  Revision 1.6  22-01-2014 (dd-mm-yyyy) freytag
+ *  changed png writing with ImageMagick to be comparable to libPNG
+ * 
  *  Revision 1.5  2009/08/03 15:23:49  koch
  *  deleted unnecessary .h
  *

+ 7 - 4
core/image/MultiChannelImage3DT.h

@@ -4,6 +4,7 @@
 #include <core/image/MultiChannelImageAccess3D.h>
 #include <core/image/ImageT.h>
 #include <core/image/MultiChannelImageT.h>
+#include <core/image/Histogram.h>
 
 #include <vector>
 #include <fstream>
@@ -139,9 +140,6 @@ public:
   /** convert to ice image */
   void convertToGrey( NICE::Image & img, int z, uint channel = 0, bool normalize = true ) const;
 
-	/** convert to ice image template */
-  void convertToGrey( NICE::ImageT<P> & img, int z, uint channel = 0, bool normalize = false ) const;
-	
   /** convert to ice colorimage */
   void convertToColor( NICE::ColorImage & img, int z, const int chan1 = 0, const int chan2 = 1, const int chan3 = 2 ) const;
 
@@ -157,8 +155,13 @@ public:
   /** calculate image statistics */
   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;
+
+  /** do a histogram equalization */
+  void equalizeHistogram( uint channel = 0 ) const;
   
   /** dump all data to RAW format: xsize, ysize, numChannels, <data> */
   void store( std::string filename ) const;

+ 48 - 65
core/image/MultiChannelImage3DT.tcc

@@ -37,17 +37,10 @@ P & MultiChannelImage3DT<P>::operator() (int x, int y, int z, uint channel)
 }
 
 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;
-  for( int z = 0; z < zsize; z++ )
+  for( int c = 0; c < numChannels; c++ )
   {
     P * datatmp = data[c];
     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 );
   
+  // some sort of correction trick hardly understandable :-)
   std::vector<double> meanVals;
   for( int z = 0; z < zsize; z++ )
   {
@@ -365,10 +359,12 @@ void MultiChannelImage3DT<P>::correctShading( uint channel ) const
     }
     sumVal /= (xsize*ysize);
     meanVals.push_back( sumVal );
+
   }
 
   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 y = 0; y < ysize; y++ )
@@ -391,90 +387,76 @@ void MultiChannelImage3DT<P>::correctShading( uint channel ) const
 }
 
 template<class P>
-Image MultiChannelImage3DT<P>::getChannel( int z, uint channel ) const
+void MultiChannelImage3DT<P>::equalizeHistogram( uint channel ) const
 {
-  assert( channel < numChannels );
+  assert(channel < numChannels );
 
-  NICE::Image img;
-  convertToGrey( img, z, channel, true );
+  for( int z = 0; z < zsize; z++ )
+  {
+    NICE::Image img = getChannel(z, channel );
+    NICE::Histogram hist(img,0,255,256);
 
-  return img;
+    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>
-ImageT<P> MultiChannelImage3DT<P>::getChannelT( int z, uint channel ) const
+Image MultiChannelImage3DT<P>::getChannel( int z, uint channel ) const
 {
   assert( channel < numChannels );
 
-  NICE::ImageT<P> img;
-  convertToGrey( img, z, channel, false );
-  
-  P min, max;
-  statistics ( min, max, channel );
-  fprintf (stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", (double)max, (double)min );
+  NICE::Image img;
+  convertToGrey( img, z, channel, true );
 
   return img;
 }
 
-/** convert to ice image */
 template<class P>
-void MultiChannelImage3DT<P>::convertToGrey( NICE::Image & img, int z, uint channel,  bool normalize ) const
+ImageT<P> MultiChannelImage3DT<P>::getChannelT( int z, uint channel ) const
 {
   assert( channel < numChannels );
 
-  P min, max;
+  //  P min, max;
+  //  statistics ( min, max, channel );
+  //  fprintf (stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", (double)max, (double)min );
 
-  if ( normalize ) {
-    statistics( min, max, channel );
-    fprintf( stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", ( double )max, ( double )min );
-  }
+  NICE::ImageT<P> img(xsize,ysize);
 
-  bool skip_assignment = false;
-
-  img.resize( xsize, ysize );
-
-  if ( normalize )
-    if ( max - min < std::numeric_limits<double>::min() )
+  long k = 0;
+  for ( int y = 0; y < ysize; y++ )
+    for( int x = 0; x < xsize; x++, k++ )
     {
-      img.set( max );
-      skip_assignment = true;
-      fprintf( stderr, "MultiChannelImage3DT::showChannel: image is uniform! (%f)\n", ( double )max );
+      img.setPixel( x, y, data[channel][z*xsize*ysize + k] );
     }
 
-
-  if ( ! skip_assignment )
-  {
-    long k = 0;
-
-    for ( int y = 0 ; y < ysize; y++ )
-    {
-      for ( int x = 0 ; x < xsize ; x++, k++ )
-      {
-        if ( normalize )
-        {
-          img.setPixel( x, y, ( int )(( data[channel][z*xsize*ysize + k] - min ) * 255 / ( max - min ) ) );
-        }
-        else
-        {
-          img.setPixel( x, y, ( int )( data[channel][z*xsize*ysize + k] ) );
-        }
-      }
-    }
-  }
+  return img;
 }
 
-/** convert to ice image template */
+/** convert to ice image */
 template<class P>
-void MultiChannelImage3DT<P>::convertToGrey( NICE::ImageT<P> & img, int z, uint channel,  bool normalize ) const
+void MultiChannelImage3DT<P>::convertToGrey( NICE::Image & img, int z, uint channel,  bool normalize ) const
 {
   assert( channel < numChannels );
 
   P min, max;
 
-  if ( normalize ) {
+  if ( normalize )
     statistics( min, max, channel );
-    fprintf( stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", ( double )max, ( double )min );
-  }
 
   bool skip_assignment = false;
 
@@ -483,9 +465,10 @@ void MultiChannelImage3DT<P>::convertToGrey( NICE::ImageT<P> & img, int z, uint
   if ( normalize )
     if ( max - min < std::numeric_limits<double>::min() )
     {
+      fprintf( stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", ( double )max, ( double )min );
       img.set( max );
       skip_assignment = true;
-      fprintf( stderr, "MultiChannelImage3DT::showChannel: image is uniform! (%f)\n", ( double )max );
+      fprintf( stderr, "MultiChannelImage3DT<>::showChannel: image is uniform! (%f)\n", ( double )max );
     }
 
 

+ 1 - 1
core/image/ippwrapper.h

@@ -203,7 +203,7 @@
   typedef struct ipcvMorphGrayState_32f IppiMorphGrayState_32f;
 
   struct OptFlowPyrLK;
-  typedef struct IppiOptFlowPyrLK;
+  typedef struct OptFlowPyrLK IppiOptFlowPyrLK;
   typedef IppiOptFlowPyrLK IppiOptFlowPyrLK_8u_C1R;
   typedef IppiOptFlowPyrLK IppiOptFlowPyrLK_16u_C1R;
   typedef IppiOptFlowPyrLK IppiOptFlowPyrLK_32f_C1R;

+ 2 - 2
core/matlabAccess/libdepend.inc

@@ -1,4 +1,4 @@
-$(call PKG_DEPEND_INT,core/basics/)
-$(call PKG_DEPEND_INT,core/vector/)
+$(call PKG_DEPEND_INT,core/basics)
+$(call PKG_DEPEND_INT,core/vector)
 $(call PKG_DEPEND_EXT_ESSENTIAL,MATIO)
 $(call PKG_DEPEND_EXT_ESSENTIAL,HDF5)

+ 3 - 3
core/optimization/libdepend.inc

@@ -1,3 +1,3 @@
- $(call PKG_DEPEND_EXT,LINAL)
- $(call PKG_DEPEND_INT,core/vector)
- $(call PKG_DEPEND_INT,core/basics)
+$(call PKG_DEPEND_EXT,LINAL)
+$(call PKG_DEPEND_INT,core/vector)
+$(call PKG_DEPEND_INT,core/basics)

+ 3 - 0
setenv.sh

@@ -24,6 +24,9 @@ for MYNICEDIR in $POSSIBLE_NICE_DIRECTORIES; do
 done
 echo Configuring NICE framework in $NICEHOME
 
+#export NICEHOME to have it accessible in child processes, e.g., in programs started on this shell aiming to read local settings, relative file names, or stuff like that
+export NICEHOME
+
 # Set the PKG_CONFIG_PATH to include the nice-core pc-files
 export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib64/pkgconfig/:/usr/lib/pkgconfig/:/usr/lib/pkgconfig/:/usr/local/lib/pkgconfig/:$NICEHOME/BUILD_`uname -m`$NICE_BUILD/pkgconfig/