From 6f76702afbff9ce0af70f887cd8a4e4d4bdd173a Mon Sep 17 00:00:00 2001 From: David Sarrut Date: Fri, 13 Jul 2012 13:36:55 +0200 Subject: [PATCH] Add Labelize function and the slot to get the mouse position --- vv/vvToolSegmentation.cxx | 242 +++++++++++++++++++++++++++++++------- vv/vvToolSegmentation.h | 17 ++- 2 files changed, 212 insertions(+), 47 deletions(-) diff --git a/vv/vvToolSegmentation.cxx b/vv/vvToolSegmentation.cxx index 0ceeb61..873a099 100644 --- a/vv/vvToolSegmentation.cxx +++ b/vv/vvToolSegmentation.cxx @@ -23,6 +23,10 @@ #include "vvToolInputSelectorWidget.h" #include "vvImageWriter.h" +// clitk +#include "clitkConnectedComponentLabeling_ggo.h" +#include "clitkConnectedComponentLabelingGenericFilter.h" + // Qt #include #include @@ -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::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(new vvROIActor); - mCurrentMaskActor = QSharedPointer(new vvROIActor); - std::vector 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(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 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 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 vvToolSegmentation::CreateMaskActor(vvImage::Pointer image, int i, int colorID, bool BGMode) +{ + static int depth = 1; + depth += 1; + QSharedPointer actor = QSharedPointer(new vvROIActor); + double * color = mDefaultLUTColor->GetTableValue(colorID % mDefaultLUTColor->GetNumberOfTableValues ()); + std::vector 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"); } //------------------------------------------------------------------------------ diff --git a/vv/vvToolSegmentation.h b/vv/vvToolSegmentation.h index 21cdaf6..84d99b5 100644 --- a/vv/vvToolSegmentation.h +++ b/vv/vvToolSegmentation.h @@ -25,6 +25,8 @@ #include "vvROIActor.h" #include "ui_vvToolSegmentation.h" +#include "vtkLookupTable.h" + //------------------------------------------------------------------------------ class vvToolSegmentation: public vvToolWidgetBase, @@ -42,13 +44,17 @@ class vvToolSegmentation: void OpenBinaryImage(); void Erode(); void Dilate(); - void UpdateAndRender(); + void Labelize(); + void RemoveLabel(); + void UpdateAndRenderNewMask(); //----------------------------------------------------- public slots: virtual void apply(); - virtual void keyPressEvent(QKeyEvent * event); + bool eventFilter(QObject *object, QEvent *event); virtual bool close(); + virtual void MousePositionChanged(int slicer); + // virtual void keyPressEvent(QKeyEvent * event); // virtual void reject(); protected: @@ -56,9 +62,16 @@ class vvToolSegmentation: Ui::vvToolSegmentation ui; QSharedPointer mRefMaskActor; QSharedPointer mCurrentMaskActor; + std::vector > mCurrentCCLActors; vvImage::Pointer mRefMaskImage; vvImage::Pointer mCurrentMaskImage; + vvImage::Pointer mCurrentCCLImage; int mKernelValue; + vtkSmartPointer mDefaultLUTColor; + enum { Mode_Default, Mode_CCL}; + int mCurrentMode; + + QSharedPointer CreateMaskActor(vvImage::Pointer image, int i, int colorID, bool BGMode=false); }; // end class vvToolSegmentation //------------------------------------------------------------------------------ -- 2.47.1