template<class args_info_type>
   BinarizeImageGenericFilter<args_info_type>::BinarizeImageGenericFilter():
     ImageToImageGenericFilter<Self>("Binarize") {
-    //    InitializeImageType<2>();
+    InitializeImageType<2>();
     InitializeImageType<3>();
-    //InitializeImageType<4>();
+    InitializeImageType<4>();
   }
   //--------------------------------------------------------------------
 
   template<class args_info_type>
   template<unsigned int Dim>
   void BinarizeImageGenericFilter<args_info_type>::InitializeImageType() {      
-    //ADD_IMAGE_TYPE(Dim, char);
+    ADD_IMAGE_TYPE(Dim, char);
     ADD_IMAGE_TYPE(Dim, short);
     ADD_IMAGE_TYPE(Dim, int);
     ADD_IMAGE_TYPE(Dim, float);
 
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>222</width>
-    <height>39</height>
+    <width>324</width>
+    <height>29</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <property name="leftMargin">
-    <number>2</number>
-   </property>
-   <property name="topMargin">
-    <number>2</number>
-   </property>
-   <property name="rightMargin">
+   <property name="margin">
     <number>2</number>
    </property>
    <item row="0" column="0">
-    <layout class="QHBoxLayout" name="horizontalLayout">
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <widget class="QLabel" name="mLabel">
        <property name="text">
      </item>
      <item>
       <widget class="QDoubleSpinBox" name="mSpinBox">
-       <property name="minimumSize">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
        <property name="decimals">
-        <number>2</number>
+        <number>1</number>
        </property>
        <property name="minimum">
         <double>-9999.000000000000000</double>
        </property>
       </widget>
      </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QPushButton" name="mButtonMinus">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="maximumSize">
+          <size>
+           <width>15</width>
+           <height>15</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>18</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>-</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="mButtonPlus">
+         <property name="maximumSize">
+          <size>
+           <width>15</width>
+           <height>15</height>
+          </size>
+         </property>
+         <property name="font">
+          <font>
+           <pointsize>18</pointsize>
+          </font>
+         </property>
+         <property name="text">
+          <string>+</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
     </layout>
    </item>
   </layout>
 
   Program:   vv
   Module:    $RCSfile: vvImageContour.cxx,v $
   Language:  C++
-  Date:      $Date: 2010/03/01 07:37:25 $
-  Version:   $Revision: 1.4 $
+  Date:      $Date: 2010/03/05 10:32:33 $
+  Version:   $Revision: 1.5 $
   Author :   David Sarrut (david.sarrut@creatis.insa-lyon.fr)
 
   Copyright (C) 2010
 //------------------------------------------------------------------------------
 
 
+//------------------------------------------------------------------------------
+void vvImageContour::setColor(double r, double g, double b) {
+  for(unsigned int i=0; i<mSquaresActorList.size(); i++) {
+    mSquaresActorList[i]->GetProperty()->SetColor(r,g,b);
+  }
+}
+//------------------------------------------------------------------------------
+
+
 //------------------------------------------------------------------------------
 void vvImageContour::hideActors() {
   if (!mSlicer) return;
 
   
 //------------------------------------------------------------------------------
-void vvImageContour::update(int value) {
+void vvImageContour::update(double value) {
   mValue= value;
   if (!mSlicer) return;
 
 
   Program:   vv
   Module:    $RCSfile: vvImageContour.h,v $
   Language:  C++
-  Date:      $Date: 2010/03/01 07:37:25 $
-  Version:   $Revision: 1.4 $
+  Date:      $Date: 2010/03/05 10:32:33 $
+  Version:   $Revision: 1.5 $
   Author :   David Sarrut (david.sarrut@creatis.insa-lyon.fr)
 
   Copyright (C) 2010
   ~vvImageContour();
 
   void setSlicer(vvSlicer * slicer);
-  void update(int value);
+  void update(double value);
   void hideActors();
   void showActors();
+  void setColor(double r, double g, double b);
 
  protected:
   vvSlicer * mSlicer;
   int mSlice;
   int mTSlice;
-  int mValue;
+  double mValue;
 
   std::vector<vtkImageClip*> mClipperList;
   std::vector<vtkMarchingSquares*> mSquaresList;
 
   Program:   vv
   Module:    $RCSfile: vvIntensityValueSlider.cxx,v $
   Language:  C++
-  Date:      $Date: 2010/03/01 07:37:25 $
-  Version:   $Revision: 1.4 $
+  Date:      $Date: 2010/03/05 10:32:33 $
+  Version:   $Revision: 1.5 $
   Author :   David Sarrut (david.sarrut@creatis.insa-lyon.fr)
 
   Copyright (C) 2008
 {
   // GUI Initialization
   setupUi(this);  
-  mValue = 0;
-  SetMaximum(1000);
-  SetMinimum(-1000);
+  mIsInteger = true;
+  mButtonPlus->setHidden(true);
+  mButtonMinus->setHidden(true);
   
   // Connect signals & slots
   connect(mSpinBox, SIGNAL(valueChanged(double)), this, SLOT(valueChangedFromSpinBox(double)));
   connect(mSlider, SIGNAL(valueChanged(int)), this, SLOT(valueChangedFromSlider(int)));
+  connect(mButtonPlus, SIGNAL(clicked()), this, SLOT(SingleStepPlusClicked()));
+  connect(mButtonMinus, SIGNAL(clicked()), this, SLOT(SingleStepMinusClicked()));
 }
 //------------------------------------------------------------------------------
 
 //------------------------------------------------------------------------------
 
 
+//------------------------------------------------------------------------------
+void vvIntensityValueSlider::SingleStepMinusClicked() {
+  mSpinBox->setSingleStep(mSpinBox->singleStep()*10);
+  mSpinBox->setDecimals(mSpinBox->decimals()-1);
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvIntensityValueSlider::SetSingleStep(double step) {
+  mSpinBox->setSingleStep(step);
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvIntensityValueSlider::SingleStepPlusClicked() {
+  mSpinBox->setSingleStep(mSpinBox->singleStep()/10);
+  mSpinBox->setDecimals(mSpinBox->decimals()+1);
+}
+//------------------------------------------------------------------------------
+
+
 //------------------------------------------------------------------------------
 void vvIntensityValueSlider::valueChangedFromSpinBox(double v) {
-  mSlider->setValue(v);
+  if (v == mValue) return;
+  mSpinBox->setValue(v);
+  v = mSpinBox->value(); // this is needed to 'round' value according to spinBox precision
+  double vv;
+  if (!mIsInteger) {
+    vv = ((v-mMin)/mWidth)/mSliderFactor;
+  }
+  else vv = v;
+  mSlider->setValue(vv);
   mValue = v;
   emit valueChanged(v);
 }
 
 
 //------------------------------------------------------------------------------
-void vvIntensityValueSlider::valueChangedFromSlider(int v) {
-  mSpinBox->setValue(v*mSliderFactor);
+void vvIntensityValueSlider::valueChangedFromSlider(int vv) {
+  double v;
+  if (!mIsInteger) {
+    v = ((double)vv*mSliderFactor)*mWidth+mMin;
+  }
+  else v= vv;
+
+  // arrondir ! ?
+
+  if (mValue == v) return;
+  mSpinBox->setValue(v);
+  mValue = v;
 }
 //------------------------------------------------------------------------------
 
 
 
 //------------------------------------------------------------------------------
-void vvIntensityValueSlider::SetValue(double d) { 
-  mSpinBox->setValue(d);
+void vvIntensityValueSlider::SetValue(double v) { 
+  mValue = v;
+  mSpinBox->setValue(v);
 }
 //------------------------------------------------------------------------------
 
 
 //------------------------------------------------------------------------------
 void vvIntensityValueSlider::SetMaximum(double max) {
-  mSlider->setMaximum(max);
+  mMax = max;
   mSpinBox->setMaximum(max);
+  
+  // If integer values : update slider max
+  if (mIsInteger == 1) {
+    mSlider->setMaximum(max);
+  }
+  else {
+    double step = mWidth/1000.0;
+    mSpinBox->setSingleStep(step);
+    mWidth = mMax-mMin;
+  }
   if (mValue > max) { SetValue(max); }
   QString tip = QString("Min = %1    Max = %2").arg(mSpinBox->minimum()).arg(max);
   setToolTip(tip);
 
 //------------------------------------------------------------------------------
 void vvIntensityValueSlider::SetMinimum(double min) {
-  mSlider->setMinimum(min);
+  mMin = min;
   mSpinBox->setMinimum(min);
+
+  if (mIsInteger == 1) {
+    mSlider->setMinimum(min);
+  }
+  else {
+    double step = mWidth/1000.0;
+    mSpinBox->setSingleStep(step);
+    mWidth = mMax-mMin;
+  }
+
   if (mValue < min) { SetValue(min); }
   QString tip = QString("Min = %1    Max = %2").arg(min).arg(mSpinBox->maximum());
   setToolTip(tip);
 
 //------------------------------------------------------------------------------
 void vvIntensityValueSlider::Update() {
+  double range[2];
+  mImage->GetFirstVTKImageData()->GetScalarRange(range);
+  mMin = range[0];
+  mMax = range[1];
+  double step = (mMax-mMin)/1000.0;
+  
   if (mImage->IsScalarTypeInteger()) {
-
+    mIsInteger = true;
     mSpinBox->setSingleStep(1.0);
     mSpinBox->setDecimals(0);
-    mSliderFactor = 1.0;
-
-    double range[2];
-    mImage->GetFirstVTKImageData()->GetScalarRange(range);
-    mMin = range[0];
-    mMax = range[1];
     mSlider->setMaximum(mMax);
     mSlider->setMinimum(mMin);
-    mSpinBox->setMaximum(mMax);
-    mSpinBox->setMinimum(mMin);
-
-    QString tip = QString("Min = %1    Max = %2").arg(mMin).arg(mMax);
-    setToolTip(tip);
+    mSlider->setSingleStep(1);
+    mSliderFactor = 1.0;
+    mWidth = 1.0;
   }
   else {
-    std::cerr << "NO floating point image yet !!" << std::endl;
-    exit(0);
+    mIsInteger = false;
+    mButtonPlus->setHidden(false);
+    mButtonMinus->setHidden(false);
+    mSpinBox->sizePolicy().setHorizontalPolicy(QSizePolicy::Expanding);
+    mSpinBox->setSingleStep(step);
+    mSpinBox->setDecimals(4);
+    mSlider->setMaximum(1000);
+    mSlider->setMinimum(0);
+    mSlider->setSingleStep(1);
+    mSliderFactor = 1.0/1000.0;
+    mWidth = mMax-mMin;
   }
+  
+  mSpinBox->setMaximum(mMax);
+  mSpinBox->setMinimum(mMin);
+  mSpinBox->setValue((mMax-mMin)/2.0+mMin);
+  
+  QString tip = QString("Min = %1    Max = %2").arg(mMin).arg(mMax);
+  setToolTip(tip);
 }
-
 //------------------------------------------------------------------------------
+
+
 
   Program:   vv
   Module:    $RCSfile: vvIntensityValueSlider.h,v $
   Language:  C++
-  Date:      $Date: 2010/02/05 09:06:46 $
-  Version:   $Revision: 1.2 $
+  Date:      $Date: 2010/03/05 10:32:33 $
+  Version:   $Revision: 1.3 $
   Author :   David Sarrut (david.sarrut@creatis.insa-lyon.fr)
 
   Copyright (C) 2008
   double GetValue() const { return mValue; }
   void SetValue(double d);
   void SetMaximum(double max);
-  void SetMinimum(double min);                         
+  void SetMinimum(double min);
+  void SetSingleStep(double step);                         
   void resetMinimum() { SetMinimum(mMin); }
   void resetMaximum() { SetMaximum(mMax); }
 
  public slots:
   void valueChangedFromSpinBox(double v);
   void valueChangedFromSlider(int v);
+  void SingleStepPlusClicked();
+  void SingleStepMinusClicked();
 
  signals:
   void valueChanged(double);
  protected:
   Ui::vvIntensityValueSlider ui;
   vvImage * mImage;
+  double mMin;
+  double mMax;
+  double mWidth;
   double mSliderFactor;
   double mValue;
-  double mMax;
-  double mMin;
+  bool mIsInteger;
 
 }; // end class vvIntensityValueSlider
 //------------------------------------------------------------------------------
 
   Program:   vv
   Module:    $RCSfile: vvToolBinarize.cxx,v $
   Language:  C++
-  Date:      $Date: 2010/03/01 15:38:09 $
-  Version:   $Revision: 1.10 $
+  Date:      $Date: 2010/03/05 10:32:33 $
+  Version:   $Revision: 1.11 $
   Author :   David Sarrut (david.sarrut@creatis.insa-lyon.fr)
 
   Copyright (C) 2008
   mInteractiveDisplayIsEnabled = mCheckBoxInteractiveDisplay->isChecked();
 
   // Connect signals & slots  
-  connect(mThresholdSlider1, SIGNAL(valueChanged(double)), this, SLOT(valueChangedT1(double)));
-  connect(mThresholdSlider2, SIGNAL(valueChanged(double)), this, SLOT(valueChangedT2(double)));
   connect(mRadioButtonLowerThan, SIGNAL(toggled(bool)), this, SLOT(enableLowerThan(bool)));
   connect(mCheckBoxUseFG, SIGNAL(toggled(bool)), this, SLOT(useFGBGtoggled(bool)));
   connect(mCheckBoxUseBG, SIGNAL(toggled(bool)), this, SLOT(useFGBGtoggled(bool)));
     RemoveVTKObjects();
   }
   else {
-    for(unsigned int i=0; i<mImageContour.size(); i++)
+    for(unsigned int i=0; i<mImageContour.size(); i++) {
       mImageContour[i]->showActors();
+      mImageContourLower[i]->showActors();
+    }
     if (mCurrentSlicerManager)
       mCurrentSlicerManager->Render();
   }
 
 //------------------------------------------------------------------------------
 void vvToolBinarize::RemoveVTKObjects() { 
-  for(unsigned int i=0; i<mImageContour.size(); i++)
+  for(unsigned int i=0; i<mImageContour.size(); i++) {
     mImageContour[i]->hideActors();
+    mImageContourLower[i]->hideActors();    
+  }
   if (mCurrentSlicerManager)
     mCurrentSlicerManager->Render();
 }
 void vvToolBinarize::enableLowerThan(bool b) {
   if (!b) {
     mThresholdSlider1->resetMaximum();
+    for(unsigned int i=0; i<mImageContour.size(); i++) {
+      mImageContourLower[i]->hideActors();    
+    }
+    mCurrentSlicerManager->Render();
   }
   else {
     valueChangedT1(mThresholdSlider1->GetValue());
+    valueChangedT2(mThresholdSlider2->GetValue());
+    for(unsigned int i=0; i<mImageContour.size(); i++) {
+      mImageContourLower[i]->showActors();    
+    }
+    mCurrentSlicerManager->Render();
   }
 }
 //------------------------------------------------------------------------------
   mBGSlider->SetMinimum(mCurrentImage->GetFirstVTKImageData()->GetScalarTypeMin());
   mFGSlider->SetValue(1);
   mBGSlider->SetValue(0);
+  mFGSlider->SetSingleStep(1);
+  mBGSlider->SetSingleStep(1);
   
   // VTK objects for interactive display
   for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
     mImageContour.push_back(new vvImageContour);
     mImageContour[i]->setSlicer(mCurrentSlicerManager->GetSlicer(i));
+    mImageContour[i]->setColor(1.0, 0.0, 0.0);
+    mImageContourLower.push_back(new vvImageContour);
+    mImageContourLower[i]->setSlicer(mCurrentSlicerManager->GetSlicer(i));
+    mImageContourLower[i]->setColor(0.0, 0.0, 1.0);
   }
   valueChangedT1(mThresholdSlider1->GetValue());
+
+  connect(mThresholdSlider1, SIGNAL(valueChanged(double)), this, SLOT(valueChangedT1(double)));
+  connect(mThresholdSlider2, SIGNAL(valueChanged(double)), this, SLOT(valueChangedT2(double)));
+
   connect(mCurrentSlicerManager,SIGNAL(UpdateSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
   connect(mCurrentSlicerManager,SIGNAL(UpdateTSlice(int,int)),this,SLOT(UpdateSlice(int, int)));
 
   if (!mCurrentSlicerManager) close();
   for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
     mImageContour[i]->update(mThresholdSlider1->GetValue());
+    if (mRadioButtonLowerThan->isChecked()) 
+      mImageContourLower[i]->update(mThresholdSlider2->GetValue());
+
   }
   mCurrentSlicerManager->Render(); 
 }
 
 //------------------------------------------------------------------------------
 void vvToolBinarize::valueChangedT2(double v) {
-  if (mRadioButtonLowerThan->isChecked()) mThresholdSlider1->SetMaximum(v);
+  //  DD("valueChangedT2");
+  if (mRadioButtonLowerThan->isChecked()) {
+    mThresholdSlider1->SetMaximum(v);
+    if (!mInteractiveDisplayIsEnabled) return;
+    for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
+      mImageContourLower[i]->update(v);
+    }
+    mCurrentSlicerManager->Render();
+  }
 }
 //------------------------------------------------------------------------------
 
 
 //------------------------------------------------------------------------------
 void vvToolBinarize::valueChangedT1(double v) {
+  //  DD("valueChangedT1");
   if (!mCurrentSlicerManager) close();
   mThresholdSlider2->SetMinimum(v);
-  int m1 = (int)lrint(v);  
+  //  int m1 = (int)lrint(v);  
   if (!mInteractiveDisplayIsEnabled) return;
   for(int i=0;i<mCurrentSlicerManager->NumberOfSlicers(); i++) {
-    mImageContour[i]->update(m1);
+    mImageContour[i]->update(v);
   }
   mCurrentSlicerManager->Render();
 }
 
   Program:   vv
   Module:    $RCSfile: vvToolBinarize.h,v $
   Language:  C++
-  Date:      $Date: 2010/03/01 07:37:25 $
-  Version:   $Revision: 1.7 $
+  Date:      $Date: 2010/03/05 10:32:33 $
+  Version:   $Revision: 1.8 $
   Author :   David Sarrut (david.sarrut@creatis.insa-lyon.fr)
 
   Copyright (C) 2010
   Ui::vvToolBinarize ui;
   args_info_clitkBinarizeImage mArgsInfo;
   std::vector<vvImageContour*> mImageContour;
+  std::vector<vvImageContour*> mImageContourLower;
   bool mInteractiveDisplayIsEnabled;
 
 }; // end class vvToolBinarize