]> Creatis software - clitk.git/blobdiff - vv/vvToolSegmentation.cxx
Add Labelize function and the slot to get the mouse position
[clitk.git] / vv / vvToolSegmentation.cxx
index 0ceeb61ac50537301c16e10fb586435f5b494339..873a099af18b4a398da00394bed01c45df0daead 100644 (file)
 #include "vvToolInputSelectorWidget.h"
 #include "vvImageWriter.h"
 
+// clitk
+#include "clitkConnectedComponentLabeling_ggo.h"
+#include "clitkConnectedComponentLabelingGenericFilter.h"
+
 // Qt
 #include <QFileDialog>
 #include <QMessageBox>
@@ -30,7 +34,7 @@
 // vtk
 #include "vtkImageContinuousErode3D.h"
 #include "vtkImageContinuousDilate3D.h"
+
 //------------------------------------------------------------------------------
 // Create the tool and automagically (I like this word) insert it in
 // the main window menu.
@@ -64,7 +68,13 @@ vvToolSegmentation::vvToolSegmentation(vvMainWindowBase * parent, Qt::WindowFlag
   AddInputSelector("Select one image");
   
   // Init
+  mRefMaskImage = NULL;
+  mCurrentMode = Mode_Default;
   mKernelValue = 3; // FIXME must be odd. If even -> not symmetrical
+  mDefaultLUTColor = vtkSmartPointer<vtkLookupTable>::New();
+  mDefaultLUTColor->SetNumberOfTableValues(256);
+#include "vvDefaultLut.h"
+  
 }
 //------------------------------------------------------------------------------
 
@@ -73,9 +83,6 @@ vvToolSegmentation::vvToolSegmentation(vvMainWindowBase * parent, Qt::WindowFlag
 vvToolSegmentation::~vvToolSegmentation()
 {
   DD("destructor");
-  mRefMaskActor->RemoveActors();
-  QWidget::close();  
-  mCurrentSlicerManager->Render();
 }
 //------------------------------------------------------------------------------
 
@@ -85,7 +92,11 @@ bool vvToolSegmentation::close()
 {
   DD("close");
   mRefMaskActor->RemoveActors();
+  DD("la");
+  mCurrentMaskActor->RemoveActors();
+  DD("here");
   QWidget::close();  
+  DD("toto");
   mCurrentSlicerManager->Render();
   return true;
 }
@@ -111,6 +122,19 @@ void vvToolSegmentation::InputIsSelected(vvSlicerManager * m)
 
   // Open mask
   OpenBinaryImage();
+  
+  // If cancel: stop
+  if (mRefMaskActor == NULL) {
+    close();
+    return;
+  }
+
+  // Update gui
+  mToolInputSelectionWidget->hide();
+
+  // Connect mouse position
+  connect(mCurrentSlicerManager, SIGNAL(MousePositionUpdatedSignal(int)),
+          this, SLOT(MousePositionChanged(int)));
 }
 //------------------------------------------------------------------------------
 
@@ -168,54 +192,59 @@ void vvToolSegmentation::OpenBinaryImage()
   mCurrentMaskImage = reader->GetOutput();
 
   // Add a new roi actor
-  mRefMaskActor = QSharedPointer<vvROIActor>(new vvROIActor);
-  mCurrentMaskActor = QSharedPointer<vvROIActor>(new vvROIActor);
-  std::vector<double> color;
-  color.push_back(1);
-  color.push_back(0);
-  color.push_back(0);
-  clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
-  roi->SetFromBinaryImage(mRefMaskImage, 1, std::string("toto"), color, filename.toStdString());
-  mRefMaskActor->SetBGMode(true);
-  mRefMaskActor->SetROI(roi);
-  mRefMaskActor->SetSlicerManager(mCurrentSlicerManager);
-  mRefMaskActor->Initialize(10, true);
+  mRefMaskActor = CreateMaskActor(mRefMaskImage, 0, 0, true);
   mRefMaskActor->SetContourVisible(true);
   mRefMaskActor->SetVisible(false);
+  mRefMaskActor->SetContourColor(0,1,0); // green contour
+  mRefMaskActor->UpdateColor();
   mRefMaskActor->Update();
 
-  clitk::DicomRT_ROI::Pointer roi2 = clitk::DicomRT_ROI::New();
-  roi2->SetFromBinaryImage(mCurrentMaskImage, 1, std::string("toto"), color, filename.toStdString());
-  mCurrentMaskActor->SetBGMode(true);
-  mCurrentMaskActor->SetROI(roi2);
-  mCurrentMaskActor->SetSlicerManager(mCurrentSlicerManager);
-  mCurrentMaskActor->Initialize(10, true);
+  mCurrentMaskActor = CreateMaskActor(mCurrentMaskImage, 1, 1, false);
+  mCurrentMaskActor->SetOverlayColor(1,0,0); // red roi
+  mRefMaskActor->UpdateColor();
   mCurrentMaskActor->Update();
 
-  // Prepare widget to get keyboard event
-  grabKeyboard();  
+  // Prepare widget to get keyboard event. With this method, the key
+  //  only work when the mouse focus is on the dialog
+  DD("here installe");
+  this->installEventFilter(this);
+  //grabKeyboard();
 }
 //------------------------------------------------------------------------------
 
 
 //------------------------------------------------------------------------------
-void vvToolSegmentation::keyPressEvent(QKeyEvent * event)
+//void vvToolSegmentation::keyPressEvent(QKeyEvent * event)
+bool vvToolSegmentation::eventFilter(QObject *object, QEvent * e)
 {
-  vvToolWidgetBase::keyPressEvent(event);
-  //DD("key");
+  // DD("key");
+  //vvToolWidgetBase::keyPressEvent(event);
   
-  if (event->text() == "e") {
-    Erode();
-  }
-  if (event->text() == "d") {
-    Dilate(); // FIXME -> extend image BB !!
-  }
-  if (event->text() == "s") {
-    vvImageWriter::Pointer writer = vvImageWriter::New();
-    writer->SetOutputFileName("a.mha");
-    writer->SetInput(mCurrentMaskImage);
-    writer->Update();
-  }
+  if (/*object == form &&*/ e->type() == QEvent::KeyPress) {
+    QKeyEvent * event = static_cast<QKeyEvent *>(e);
+    
+    if (event->text() == "e") {
+      Erode();
+    }
+    if (event->text() == "d") {
+      Dilate(); // FIXME -> extend image BB !!
+    }
+    if (event->text() == "l") {
+      Labelize(); 
+    }
+    if (event->text() == "r") { // "Remove" one label
+      if (mCurrentMode == Mode_CCL) RemoveLabel();
+    }
+    if (event->text() == "s") {
+      vvImageWriter::Pointer writer = vvImageWriter::New();
+      writer->SetOutputFileName("a.mha");
+      writer->SetInput(mCurrentMaskImage);
+      writer->Update();
+    }
+    //mMainWindow->keyPressEvent(event);
+    vvToolWidgetBase::keyPressEvent(event);
+  }         
+  return QObject::eventFilter(object, e);
 }
 //------------------------------------------------------------------------------
 
@@ -231,7 +260,7 @@ void vvToolSegmentation::Erode()
   erode->Update();
   image->DeepCopy(erode->GetOutput());
   image->Update();
-  UpdateAndRender();
+  UpdateAndRenderNewMask();
   erode->Delete();
   QApplication::restoreOverrideCursor();
 }
@@ -249,7 +278,7 @@ void vvToolSegmentation::Dilate()
   dilate->Update();
   image->DeepCopy(dilate->GetOutput());
   image->Update();
-  UpdateAndRender();
+  UpdateAndRenderNewMask();
   dilate->Delete();
   QApplication::restoreOverrideCursor();
 }
@@ -257,18 +286,141 @@ void vvToolSegmentation::Dilate()
 
 
 //------------------------------------------------------------------------------
-void vvToolSegmentation::UpdateAndRender()
+void vvToolSegmentation::UpdateAndRenderNewMask()
 {
   bool visible = mCurrentMaskActor->IsVisible();
   bool cvisible = mCurrentMaskActor->IsContourVisible();
   mCurrentMaskActor->SetVisible(false);
   mCurrentMaskActor->SetContourVisible(false);
-  // mCurrentSlicerManager->Render();
-
-  //mCurrentMaskActor->RemoveActors();
   mCurrentMaskActor->UpdateImage();
   mCurrentMaskActor->SetVisible(visible);
   mCurrentMaskActor->SetContourVisible(cvisible);
+
+  mCurrentSlicerManager->Render();
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::Labelize()
+{
+  DD("Labelize");
+  // Waiting cursos
+  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+  
+  // Build CCL filter
+  vtkImageData* image = mCurrentMaskImage->GetVTKImages()[0];
+  typedef args_info_clitkConnectedComponentLabeling ArgsInfoType;
+  ArgsInfoType a;
+  cmdline_parser_clitkConnectedComponentLabeling_init(&a);
+  a.inputBG_arg = 0;
+  a.full_flag = false;  // FIXME set by gui
+  a.minSize_arg = 100;  // FIXME set by gui 
+  typedef clitk::ConnectedComponentLabelingGenericFilter<ArgsInfoType> FilterType;
+  FilterType::Pointer filter = FilterType::New();
+  filter->SetArgsInfo(a);
+  filter->SetInputVVImage(mCurrentMaskImage);
+  filter->SetIOVerbose(true);  
+  filter->Update();
+  DD(filter->GetOriginalNumberOfObjects());
+  DD(filter->GetSizeOfObjectsInPixels().size());
+  mCurrentCCLImage = filter->GetOutputVVImage();
+  DDV(filter->GetSizeOfObjectsInPixels(), filter->GetSizeOfObjectsInPixels().size());
+  DD("filter done");
+
+  /*
+  // DEBUG
+  vvImageWriter::Pointer writer = vvImageWriter::New();
+  writer->SetInput(mCurrentCCLImage);
+  writer->SetOutputFileName("bidon-ccl.mha");
+  writer->Update(); 
+  DD(mCurrentCCLImage->IsScalarTypeInteger());
+  */
+  
+  // Create actors 
+  int n = filter->GetSizeOfObjectsInPixels().size();
+  for(int i=1; i<std::min(n,10); i++) { // Start at 1 because 0 is BG. FIXME max 10
+    DD(i);
+    QSharedPointer<vvROIActor> actor = CreateMaskActor(mCurrentCCLImage, i, i+1, false); 
+    mCurrentCCLActors.push_back( actor );
+    actor->Update();    
+  }
+  mCurrentMaskActor->SetVisible(false);
+  mCurrentMaskActor->Update();
   mCurrentSlicerManager->Render();
+  
+  // UpdateAndRender();
+  mCurrentMode = Mode_CCL;
+  QApplication::restoreOverrideCursor();
+}
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+QSharedPointer<vvROIActor> vvToolSegmentation::CreateMaskActor(vvImage::Pointer image, int i, int colorID, bool BGMode)
+{
+  static int depth = 1;
+  depth += 1;
+  QSharedPointer<vvROIActor> actor = QSharedPointer<vvROIActor>(new vvROIActor);
+  double * color = mDefaultLUTColor->GetTableValue(colorID % mDefaultLUTColor->GetNumberOfTableValues ());
+  std::vector<double> c;
+  c.push_back(color[0]);
+  c.push_back(color[1]);
+  c.push_back(color[2]);
+  clitk::DicomRT_ROI::Pointer roi = clitk::DicomRT_ROI::New();
+  roi->SetFromBinaryImage(image, i, std::string("toto"), c, std::string("titi"));
+  if (BGMode) {
+    actor->SetBGMode(true);
+  }
+  else {
+    DD("FG mode");
+    roi->SetForegroundValueLabelImage(i); // FG mode
+    actor->SetBGMode(false); // FG mode
+  }
+  actor->SetROI(roi);
+  actor->SetSlicerManager(mCurrentSlicerManager);
+  actor->Initialize(depth+i, true); // +1 to start at 1 not 0
+  actor->SetContourVisible(false);
+  actor->SetVisible(true);
+  return actor;
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::MousePositionChanged(int slicer)
+{
+  if (mCurrentMode == Mode_Default) return; // Do nothing in this case
+
+  double x = mCurrentSlicerManager->GetSlicer(slicer)->GetCurrentPosition()[0];
+  double y = mCurrentSlicerManager->GetSlicer(slicer)->GetCurrentPosition()[1];
+  double z = mCurrentSlicerManager->GetSlicer(slicer)->GetCurrentPosition()[2];
+  vtkImageData * image = mCurrentCCLImage->GetFirstVTKImageData();
+  double Xover = (x - image->GetOrigin()[0]) / image->GetSpacing()[0];
+  double Yover = (y - image->GetOrigin()[1]) / image->GetSpacing()[1];
+  double Zover = (z - image->GetOrigin()[2]) / image->GetSpacing()[2];
+  int ix, iy, iz;
+  
+  if (Xover >= image->GetWholeExtent()[0] &&
+      Xover <= image->GetWholeExtent()[1] &&
+      Yover >= image->GetWholeExtent()[2] &&
+      Yover <= image->GetWholeExtent()[3] &&
+      Zover >= image->GetWholeExtent()[4] &&
+      Zover <= image->GetWholeExtent()[5]) {
+    double valueOver = 
+      mCurrentSlicerManager->GetSlicer(0)->GetScalarComponentAsDouble(image, Xover, Yover, Zover, ix, iy, iz, 0);
+    // DD(Xover); DD(Yover); DD(Zover);
+    // DD(ix); DD(iy); DD(iz);
+    // DD(valueOver);
+  }
+  else {
+    // DD("out of mask");
+  }
+
+}
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+void vvToolSegmentation::RemoveLabel() {
+  DD("RemoveLabel");
 }
 //------------------------------------------------------------------------------