From e34e0e0eb662c6c7fa3681f53aac959fef4b4f73 Mon Sep 17 00:00:00 2001 From: David Sarrut Date: Mon, 16 Jul 2012 16:28:08 +0200 Subject: [PATCH] First version with Merge and remove label --- vv/vvToolSegmentation.cxx | 165 +++++++++++++++++++++++++------------- vv/vvToolSegmentation.h | 10 ++- 2 files changed, 115 insertions(+), 60 deletions(-) diff --git a/vv/vvToolSegmentation.cxx b/vv/vvToolSegmentation.cxx index 873a099..9bd9365 100644 --- a/vv/vvToolSegmentation.cxx +++ b/vv/vvToolSegmentation.cxx @@ -14,7 +14,7 @@ - BSD See included LICENSE.txt file - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html -===========================================================================**/ + ===========================================================================**/ // vv #include "vvToolSegmentation.h" @@ -34,6 +34,7 @@ // vtk #include "vtkImageContinuousErode3D.h" #include "vtkImageContinuousDilate3D.h" +#include "vtkRenderWindow.h" //------------------------------------------------------------------------------ // Create the tool and automagically (I like this word) insert it in @@ -69,7 +70,7 @@ vvToolSegmentation::vvToolSegmentation(vvMainWindowBase * parent, Qt::WindowFlag // Init mRefMaskImage = NULL; - mCurrentMode = Mode_Default; + mCurrentState = State_Default; mKernelValue = 3; // FIXME must be odd. If even -> not symmetrical mDefaultLUTColor = vtkSmartPointer::New(); mDefaultLUTColor->SetNumberOfTableValues(256); @@ -90,13 +91,16 @@ vvToolSegmentation::~vvToolSegmentation() //------------------------------------------------------------------------------ bool vvToolSegmentation::close() { - DD("close"); - mRefMaskActor->RemoveActors(); - DD("la"); - mCurrentMaskActor->RemoveActors(); - DD("here"); + DD("remo ref"); + if (mRefMaskActor) mRefMaskActor->RemoveActors(); + DD("remo mask"); + if (mCurrentMaskActor) mCurrentMaskActor->RemoveActors(); + for(int i=0; iRemoveActors(); + } + DD("wclose"); QWidget::close(); - DD("toto"); mCurrentSlicerManager->Render(); return true; } @@ -135,6 +139,8 @@ void vvToolSegmentation::InputIsSelected(vvSlicerManager * m) // Connect mouse position connect(mCurrentSlicerManager, SIGNAL(MousePositionUpdatedSignal(int)), this, SLOT(MousePositionChanged(int))); + connect(mCurrentSlicerManager, SIGNAL(KeyPressedSignal(std::string)), + this, SLOT(KeyPressed(std::string))); } //------------------------------------------------------------------------------ @@ -191,60 +197,86 @@ void vvToolSegmentation::OpenBinaryImage() reader->Update(vvImageReader::IMAGE); mCurrentMaskImage = reader->GetOutput(); - // Add a new roi actor - mRefMaskActor = CreateMaskActor(mRefMaskImage, 0, 0, true); + // Add a new roi actor for the current mask + mCurrentMaskActor = CreateMaskActor(mCurrentMaskImage, 1, 0, false); + mCurrentMaskActor->Update(); // default color is red + + // Add a mask actor for the reference + mRefMaskActor = CreateMaskActor(mRefMaskImage, 0, 1, true); mRefMaskActor->SetContourVisible(true); mRefMaskActor->SetVisible(false); mRefMaskActor->SetContourColor(0,1,0); // green contour mRefMaskActor->UpdateColor(); mRefMaskActor->Update(); +} +//------------------------------------------------------------------------------ - mCurrentMaskActor = CreateMaskActor(mCurrentMaskImage, 1, 1, false); - mCurrentMaskActor->SetOverlayColor(1,0,0); // red roi - mRefMaskActor->UpdateColor(); - mCurrentMaskActor->Update(); - // 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::KeyPressed(std::string KeyPress) +{ + if (KeyPress == "e") { + Erode(); + } + if (KeyPress == "d") { + Dilate(); // FIXME -> extend image BB !! + } + if (KeyPress == "L") { + Labelize(); + } + if (KeyPress == "m") { + Merge(); + } + if (KeyPress == "s") { // Supress "Remove" one label + if (mCurrentState == State_CCL) RemoveLabel(); + } + if (KeyPress == "t") { // display remove ref contour + mRefMaskActor->SetContourVisible(!mRefMaskActor->IsContourVisible()); + mRefMaskActor->UpdateColor(); + mCurrentSlicerManager->Render(); + } + if (KeyPress == "w") { + vvImageWriter::Pointer writer = vvImageWriter::New(); + writer->SetOutputFileName("a.mha"); + writer->SetInput(mCurrentMaskImage); + writer->Update(); + } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ -//void vvToolSegmentation::keyPressEvent(QKeyEvent * event) -bool vvToolSegmentation::eventFilter(QObject *object, QEvent * e) +void vvToolSegmentation::Merge() { - // DD("key"); - //vvToolWidgetBase::keyPressEvent(event); + if (mCurrentState != State_CCL) return; - 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 !! + DD("Merge"); + // Remove actors + for(int i=0; iSetVisible(false); + mCurrentCCLActors[i]->RemoveActors(); } - 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); + } + mCurrentCCLActors.clear(); + + // Compute new mask + vtkImageData * ccl = mCurrentCCLImage->GetFirstVTKImageData(); + vtkImageData * mask = mCurrentMaskImage->GetFirstVTKImageData(); + int * pCCL = (int*)ccl->GetScalarPointer(); + char * pPix = (char*)mask->GetScalarPointer(); + for(uint i=0; iGetNumberOfPoints(); i++) { + if (pCCL[i] == 0) pPix[i] = 0; // copy BG + } + + // Display new mask and remove ccl + mCurrentCCLImage->Reset(); + mCurrentMaskActor->RemoveActors(); // kill it + mCurrentMaskActor = CreateMaskActor(mCurrentMaskImage, 1, 0, false); // renew + mCurrentMaskActor->Update(); + mCurrentMaskActor->SetVisible(true); + mCurrentSlicerManager->Render(); + mCurrentState = State_Default; } //------------------------------------------------------------------------------ @@ -253,6 +285,9 @@ bool vvToolSegmentation::eventFilter(QObject *object, QEvent * e) void vvToolSegmentation::Erode() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + // Merge labels if needed + Merge(); + // Get image and start erosion vtkImageContinuousErode3D* erode = vtkImageContinuousErode3D::New(); erode->SetKernelSize(mKernelValue,mKernelValue,mKernelValue); vtkImageData* image = mCurrentMaskImage->GetVTKImages()[0]; @@ -271,6 +306,9 @@ void vvToolSegmentation::Erode() void vvToolSegmentation::Dilate() { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + // Merge labels if needed + Merge(); + // Get image and start dilatation vtkImageContinuousDilate3D* dilate = vtkImageContinuousDilate3D::New(); dilate->SetKernelSize(mKernelValue,mKernelValue,mKernelValue); vtkImageData* image = mCurrentMaskImage->GetVTKImages()[0]; @@ -303,9 +341,11 @@ void vvToolSegmentation::UpdateAndRenderNewMask() //------------------------------------------------------------------------------ void vvToolSegmentation::Labelize() { + if (mCurrentState == State_CCL) return; // Do nothing in this case DD("Labelize"); // Waiting cursos QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + mCurrentMaskActor->SetVisible(false); // Build CCL filter vtkImageData* image = mCurrentMaskImage->GetVTKImages()[0]; @@ -318,7 +358,7 @@ void vvToolSegmentation::Labelize() typedef clitk::ConnectedComponentLabelingGenericFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetArgsInfo(a); - filter->SetInputVVImage(mCurrentMaskImage); + filter->SetInputVVImage(mCurrentMaskImage); // FIXME Check type is ok ? convert float ? filter->SetIOVerbose(true); filter->Update(); DD(filter->GetOriginalNumberOfObjects()); @@ -338,18 +378,17 @@ void vvToolSegmentation::Labelize() // 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(); + // mCurrentMaskActor->Update(); mCurrentSlicerManager->Render(); // UpdateAndRender(); - mCurrentMode = Mode_CCL; + mCurrentState = State_CCL; QApplication::restoreOverrideCursor(); } //------------------------------------------------------------------------------ @@ -371,7 +410,6 @@ QSharedPointer vvToolSegmentation::CreateMaskActor(vvImage::Pointer actor->SetBGMode(true); } else { - DD("FG mode"); roi->SetForegroundValueLabelImage(i); // FG mode actor->SetBGMode(false); // FG mode } @@ -388,7 +426,7 @@ QSharedPointer vvToolSegmentation::CreateMaskActor(vvImage::Pointer //------------------------------------------------------------------------------ void vvToolSegmentation::MousePositionChanged(int slicer) { - if (mCurrentMode == Mode_Default) return; // Do nothing in this case + if (mCurrentState == State_Default) return; // Do nothing in this case double x = mCurrentSlicerManager->GetSlicer(slicer)->GetCurrentPosition()[0]; double y = mCurrentSlicerManager->GetSlicer(slicer)->GetCurrentPosition()[1]; @@ -405,7 +443,7 @@ void vvToolSegmentation::MousePositionChanged(int slicer) Yover <= image->GetWholeExtent()[3] && Zover >= image->GetWholeExtent()[4] && Zover <= image->GetWholeExtent()[5]) { - double valueOver = + mCurrentLabelUnderMousePointer = mCurrentSlicerManager->GetSlicer(0)->GetScalarComponentAsDouble(image, Xover, Yover, Zover, ix, iy, iz, 0); // DD(Xover); DD(Yover); DD(Zover); // DD(ix); DD(iy); DD(iz); @@ -413,8 +451,9 @@ void vvToolSegmentation::MousePositionChanged(int slicer) } else { // DD("out of mask"); + mCurrentLabelUnderMousePointer = 0; } - + // DD(mCurrentLabelUnderMousePointer); } //------------------------------------------------------------------------------ @@ -422,5 +461,17 @@ void vvToolSegmentation::MousePositionChanged(int slicer) //------------------------------------------------------------------------------ void vvToolSegmentation::RemoveLabel() { DD("RemoveLabel"); + if (mCurrentLabelUnderMousePointer == 0) return; + // First actor=0 and is label 1. Label 0 is not an actor, it is BG + int actorNumber = mCurrentLabelUnderMousePointer-1; + // Set actor invisible + mCurrentCCLActors[actorNumber]->SetVisible(false); + mCurrentSlicerManager->Render(); + // Set image label + vtkImageData * image = mCurrentCCLImage->GetFirstVTKImageData(); + int * pPix = (int*)image->GetScalarPointer(); + for(uint i=0; iGetNumberOfPoints(); i++) { + if (pPix[i] == mCurrentLabelUnderMousePointer) pPix[i] = 0; + } } //------------------------------------------------------------------------------ diff --git a/vv/vvToolSegmentation.h b/vv/vvToolSegmentation.h index 84d99b5..20f904d 100644 --- a/vv/vvToolSegmentation.h +++ b/vv/vvToolSegmentation.h @@ -45,13 +45,15 @@ class vvToolSegmentation: void Erode(); void Dilate(); void Labelize(); + void Merge(); void RemoveLabel(); void UpdateAndRenderNewMask(); //----------------------------------------------------- public slots: virtual void apply(); - bool eventFilter(QObject *object, QEvent *event); + // bool eventFilter(QObject *object, QEvent *event); + void KeyPressed(std::string KeyPress); virtual bool close(); virtual void MousePositionChanged(int slicer); // virtual void keyPressEvent(QKeyEvent * event); @@ -68,10 +70,12 @@ class vvToolSegmentation: vvImage::Pointer mCurrentCCLImage; int mKernelValue; vtkSmartPointer mDefaultLUTColor; - enum { Mode_Default, Mode_CCL}; - int mCurrentMode; + enum { State_Default, State_CCL}; + int mCurrentState; QSharedPointer CreateMaskActor(vvImage::Pointer image, int i, int colorID, bool BGMode=false); + + double mCurrentLabelUnderMousePointer; }; // end class vvToolSegmentation //------------------------------------------------------------------------------ -- 2.47.1