diff --git a/Modules/Segmentation/Algorithms/mitkSurfaceStampImageFilter.cpp b/Modules/Segmentation/Algorithms/mitkSurfaceStampImageFilter.cpp index 9684f93931..63028d82f8 100644 --- a/Modules/Segmentation/Algorithms/mitkSurfaceStampImageFilter.cpp +++ b/Modules/Segmentation/Algorithms/mitkSurfaceStampImageFilter.cpp @@ -1,301 +1,299 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSurfaceStampImageFilter.h" #include "mitkTimeHelper.h" #include "mitkImageWriteAccessor.h" #include "mitkImageAccessByItk.h" #include #include #include #include #include #include #include #include mitk::SurfaceStampImageFilter::SurfaceStampImageFilter() : m_MakeOutputBinary( false ), m_OverwriteBackground( false ), m_ForegroundValue( 1.0 ), m_BackgroundValue( 0.0 ) { } mitk::SurfaceStampImageFilter::~SurfaceStampImageFilter() { } void mitk::SurfaceStampImageFilter::GenerateInputRequestedRegion() { mitk::Image* outputImage = this->GetOutput(); if((outputImage->IsInitialized()==false) ) return; GenerateTimeInInputRegion(outputImage, const_cast< mitk::Image * > ( this->GetInput() )); } void mitk::SurfaceStampImageFilter::GenerateOutputInformation() { mitk::Image::ConstPointer inputImage = this->GetInput(); mitk::Image::Pointer outputImage = this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); if( inputImage.IsNull() || (inputImage->IsInitialized() == false) || (inputImage->GetTimeGeometry() == NULL)) return; if (m_MakeOutputBinary) outputImage->Initialize(mitk::MakeScalarPixelType() , *inputImage->GetTimeGeometry()); else outputImage->Initialize(inputImage->GetPixelType(), *inputImage->GetTimeGeometry()); outputImage->SetPropertyList(inputImage->GetPropertyList()->Clone()); } void mitk::SurfaceStampImageFilter::SetSurface(mitk::Surface *surface) { m_Surface = surface; } void mitk::SurfaceStampImageFilter::GenerateData() { mitk::Image::ConstPointer inputImage = this->GetInput(); if (inputImage.IsNull()) return; mitk::Image::Pointer outputImage = this->GetOutput(); if(outputImage->IsInitialized()==false ) return; if (m_Surface.IsNull()) return; mitk::Image::RegionType outputRegion = outputImage->GetRequestedRegion(); int tstart=outputRegion.GetIndex(3); int tmax=tstart+outputRegion.GetSize(3); if ( tmax > 0) { int t; for(t=tstart;tSurfaceStamp( t ); } } else { this->SurfaceStamp( 0 ); } } void mitk::SurfaceStampImageFilter::SurfaceStamp(int time) { mitk::Image::Pointer inputImage = this->GetInput(); const mitk::TimeGeometry *surfaceTimeGeometry = GetInput()->GetTimeGeometry(); const mitk::TimeGeometry *imageTimeGeometry = inputImage->GetTimeGeometry(); // Convert time step from image time-frame to surface time-frame mitk::TimePointType matchingTimePoint = imageTimeGeometry->TimeStepToTimePoint(time); mitk::TimeStepType surfaceTimeStep = surfaceTimeGeometry->TimePointToTimeStep(matchingTimePoint); vtkPolyData * polydata = m_Surface->GetVtkPolyData( surfaceTimeStep ); if (!polydata) mitkThrow() << "Polydata is null."; vtkSmartPointer transformFilter = vtkSmartPointer::New(); transformFilter->SetInputData(polydata); // transformFilter->ReleaseDataFlagOn(); vtkSmartPointer transform = vtkSmartPointer::New(); BaseGeometry::Pointer geometry = surfaceTimeGeometry->GetGeometryForTimeStep( surfaceTimeStep ); - //MLI TODO - //geometry->TransferItkToVtkTransform(); + transform->PostMultiply(); transform->Concatenate(geometry->GetVtkTransform()->GetMatrix()); // take image geometry into account. vtk-Image information will be changed to unit spacing and zero origin below. BaseGeometry::Pointer imageGeometry = imageTimeGeometry->GetGeometryForTimeStep(time); - //MLI TODO - //imageGeometry->TransferItkToVtkTransform(); + transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse()); transformFilter->SetTransform(transform); transformFilter->Update(); polydata = transformFilter->GetOutput(); if ( !polydata || !polydata->GetNumberOfPoints() ) mitkThrow() << "Polydata retrieved from transformation is null or has no points."; MeshType::Pointer mesh = MeshType::New(); mesh->SetCellsAllocationMethod( MeshType::CellsAllocatedDynamicallyCellByCell ); unsigned int numberOfPoints = polydata->GetNumberOfPoints(); mesh->GetPoints()->Reserve( numberOfPoints ); vtkPoints* points = polydata->GetPoints(); MeshType::PointType point; for( int i=0; i < numberOfPoints; i++ ) { double* aux = points->GetPoint(i); point[0] = aux[0]; point[1] = aux[1]; point[2] = aux[2]; mesh->SetPoint( i, point ); } // Load the polygons into the itk::Mesh typedef MeshType::CellAutoPointer CellAutoPointerType; typedef MeshType::CellType CellType; typedef itk::TriangleCell< CellType > TriangleCellType; typedef MeshType::PointIdentifier PointIdentifierType; typedef MeshType::CellIdentifier CellIdentifierType; // Read the number of polygons CellIdentifierType numberOfPolygons = 0; numberOfPolygons = polydata->GetNumberOfPolys(); vtkCellArray* polys = polydata->GetPolys(); PointIdentifierType numberOfCellPoints = 3; CellIdentifierType i = 0; for (i=0; iGetCell(i); cellIds = vcell->GetPointIds(); CellAutoPointerType cell; TriangleCellType * triangleCell = new TriangleCellType; PointIdentifierType k; for( k = 0; k < numberOfCellPoints; k++ ) { triangleCell->SetPointId( k, cellIds->GetId(k) ); } cell.TakeOwnership( triangleCell ); mesh->SetCell( i, cell ); } if ( !mesh->GetNumberOfPoints() ) mitkThrow() << "Generated itk mesh is empty."; if (m_MakeOutputBinary) { this->SurfaceStampBinaryOutputProcessing( mesh ); } else { AccessFixedDimensionByItk_1(inputImage, SurfaceStampProcessing, 3, mesh); } } void mitk::SurfaceStampImageFilter::SurfaceStampBinaryOutputProcessing( MeshType* mesh ) { mitk::Image* inputImage = const_cast< mitk::Image* >( this->GetInput() ); mitk::Image::Pointer outputImage = this->GetOutput(); typedef itk::Image< unsigned char, 3 > BinaryImageType; BinaryImageType::Pointer itkInputImage; mitk::CastToItkImage(inputImage, itkInputImage); typedef itk::TriangleMeshToBinaryImageFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput(mesh); filter->SetInfoImage(itkInputImage); filter->SetInsideValue(1); filter->SetOutsideValue(0); filter->Update(); BinaryImageType::Pointer resultImage = filter->GetOutput(); resultImage->DisconnectPipeline(); mitk::CastToMitkImage(resultImage, outputImage); } template < typename TPixel > void mitk::SurfaceStampImageFilter::SurfaceStampProcessing(itk::Image< TPixel, 3 >* input, MeshType* mesh) { typedef itk::Image< TPixel, 3 > ImageType; typedef itk::Image< unsigned char, 3 > BinaryImageType; typedef itk::TriangleMeshToBinaryImageFilter FilterType; BinaryImageType::Pointer binaryInput = BinaryImageType::New(); binaryInput->SetSpacing( input->GetSpacing() ); binaryInput->SetOrigin( input->GetOrigin() ); binaryInput->SetDirection( input->GetDirection() ); binaryInput->SetRegions( input->GetLargestPossibleRegion() ); binaryInput->Allocate(); binaryInput->FillBuffer(0); FilterType::Pointer filter = FilterType::New(); filter->SetInput(mesh); filter->SetInfoImage(binaryInput); filter->SetInsideValue(1); filter->SetOutsideValue(0); filter->Update(); BinaryImageType::Pointer resultImage = filter->GetOutput(); resultImage->DisconnectPipeline(); mitk::Image::Pointer outputImage = this->GetOutput(); typename ImageType::Pointer itkOutputImage; mitk::CastToItkImage(outputImage, itkOutputImage); typedef itk::ImageRegionConstIterator< BinaryImageType > BinaryIteratorType; typedef itk::ImageRegionConstIterator< ImageType > InputIteratorType; typedef itk::ImageRegionIterator< ImageType > OutputIteratorType; BinaryIteratorType sourceIter( resultImage, resultImage->GetLargestPossibleRegion() ); sourceIter.GoToBegin(); InputIteratorType inputIter( input, input->GetLargestPossibleRegion() ); inputIter.GoToBegin(); OutputIteratorType outputIter( itkOutputImage, itkOutputImage->GetLargestPossibleRegion() ); outputIter.GoToBegin(); typename ImageType::PixelType inputValue; unsigned char sourceValue; typename ImageType::PixelType fgValue = static_cast< typename ImageType::PixelType >(m_ForegroundValue); typename ImageType::PixelType bgValue = static_cast< typename ImageType::PixelType >(m_BackgroundValue); while ( !sourceIter.IsAtEnd() ) { sourceValue = static_cast< unsigned char >(sourceIter.Get()); inputValue = static_cast< typename ImageType::PixelType >(inputIter.Get()); if (sourceValue != 0) outputIter.Set( fgValue ); else if (m_OverwriteBackground) outputIter.Set( bgValue ); else outputIter.Set( inputValue ); ++sourceIter; ++inputIter; ++outputIter; } } \ No newline at end of file diff --git a/Modules/Segmentation/Controllers/mitkSliceBasedInterpolationController.cpp b/Modules/Segmentation/Controllers/mitkSliceBasedInterpolationController.cpp index ae2524d013..7a96345395 100644 --- a/Modules/Segmentation/Controllers/mitkSliceBasedInterpolationController.cpp +++ b/Modules/Segmentation/Controllers/mitkSliceBasedInterpolationController.cpp @@ -1,419 +1,420 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkSliceBasedInterpolationController.h" #include "mitkImageCast.h" #include "mitkImageAccessByItk.h" #include "mitkImageTimeSelector.h" #include "mitkExtractSliceFilter.h" #include "mitkImageReadAccessor.h" #include "mitkShapeBasedInterpolationAlgorithm.h" #include #include #include mitk::SliceBasedInterpolationController::InterpolatorMapType mitk::SliceBasedInterpolationController::s_InterpolatorForImage; // static member initialization mitk::SliceBasedInterpolationController* mitk::SliceBasedInterpolationController::InterpolatorForImage(const Image* image) { InterpolatorMapType::iterator iter = s_InterpolatorForImage.find( image ); if ( iter != s_InterpolatorForImage.end() ) { return iter->second; } else { return NULL; } } mitk::SliceBasedInterpolationController::SliceBasedInterpolationController() : m_WorkingImage(NULL), m_ReferenceImage(NULL) { } mitk::SliceBasedInterpolationController::~SliceBasedInterpolationController() { // remove this from the list of interpolators for ( InterpolatorMapType::iterator iter = s_InterpolatorForImage.begin(); iter != s_InterpolatorForImage.end(); ++iter ) { if (iter->second == this) { s_InterpolatorForImage.erase( iter ); break; } } } void mitk::SliceBasedInterpolationController::ResetLabelCount() { m_LabelCountInSlice.clear(); int numberOfLabels = m_WorkingImage->GetNumberOfLabels(); m_LabelCountInSlice.resize( m_WorkingImage->GetTimeSteps() ); for (unsigned int timeStep = 0; timeStep < m_WorkingImage->GetTimeSteps(); ++timeStep) { m_LabelCountInSlice[timeStep].resize(3); for (unsigned int dim = 0; dim < 3; ++dim) { m_LabelCountInSlice[timeStep][dim].clear(); m_LabelCountInSlice[timeStep][dim].resize( m_WorkingImage->GetDimension(dim) ); for (unsigned int slice = 0; slice < m_WorkingImage->GetDimension(dim); ++slice) { m_LabelCountInSlice[timeStep][dim][slice].clear(); m_LabelCountInSlice[timeStep][dim][slice].resize( numberOfLabels ); m_LabelCountInSlice[timeStep][dim][slice].assign( numberOfLabels, 0 ); } } } } void mitk::SliceBasedInterpolationController::SetWorkingImage( LabelSetImage* newImage ) { if (m_WorkingImage != newImage) { // delete the current working image from the list of interpolators InterpolatorMapType::iterator iter = s_InterpolatorForImage.find( m_WorkingImage); if ( iter != s_InterpolatorForImage.end() ) { s_InterpolatorForImage.erase( iter ); } m_WorkingImage = newImage; s_InterpolatorForImage.insert( std::make_pair( m_WorkingImage, this ) ); } this->ResetLabelCount(); AccessFixedDimensionByItk_1( m_WorkingImage, ScanImageITKProcessing, 3, 0 ); // for all timesteps, scan whole image: TODO: enable this again for 3D+time /* for (unsigned int timeStep = 0; timeStep < m_WorkingImage->GetTimeSteps(); ++timeStep) { ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New(); timeSelector->SetInput( m_WorkingImage ); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); Image::Pointer segmentation3D = timeSelector->GetOutput(); this->SetChangedVolume( segmentation3D.GetPointer(), timeStep ); } */ // this->Modified(); } void mitk::SliceBasedInterpolationController::SetReferenceImage( Image* newImage ) { if (!newImage) return; m_ReferenceImage = newImage; // ensure the reference image has the same dimensionality and extents as the segmentation image if ( m_WorkingImage.IsNull() || m_ReferenceImage->GetDimension() != m_WorkingImage->GetDimension() || m_ReferenceImage->GetPixelType().GetNumberOfComponents() != 1 || m_WorkingImage->GetPixelType().GetNumberOfComponents() != 1 ) { MITK_WARN << "Segmentation image has different image characteristics than reference image." << std::endl; m_ReferenceImage = NULL; return; } for (unsigned int dim = 0; dim < m_WorkingImage->GetDimension(); ++dim) { if ( m_ReferenceImage->GetDimension(dim) != m_WorkingImage->GetDimension(dim) ) { MITK_WARN << "original patient image does not match segmentation (different extent in dimension " << dim << "), ignoring patient image" << std::endl; m_ReferenceImage = NULL; return; } } } void mitk::SliceBasedInterpolationController::SetChangedSlice( const Image* slice, unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep ) { if ( !slice ) return; if ( slice->GetDimension() != 2 ) return; if ( sliceDimension > 2 ) return; if ( m_WorkingImage.IsNull() ) return; // check if the number of labels has changed int numberOfLabels = m_WorkingImage->GetNumberOfLabels(); if (m_LabelCountInSlice[0][0][0].size() != numberOfLabels) return; unsigned int dim0(0); unsigned int dim1(1); // determine the other two dimensions switch (sliceDimension) { default: case 2: dim0 = 0; dim1 = 1; break; case 1: dim0 = 0; dim1 = 2; break; case 0: dim0 = 1; dim1 = 2; break; } AccessFixedDimensionByItk_1( slice, ScanSliceITKProcessing, 2, SetChangedSliceOptions(sliceDimension, sliceIndex, dim0, dim1, timeStep) ); // this->Modified(); } template < typename PixelType > void mitk::SliceBasedInterpolationController::ScanSliceITKProcessing( const itk::Image* input, const SetChangedSliceOptions& options ) { unsigned int timeStep = options.timeStep; unsigned int sliceDimension = options.sliceDimension; unsigned int sliceIndex = options.sliceIndex; if ( sliceDimension > 2 ) return; if ( sliceIndex >= m_LabelCountInSlice[timeStep][sliceDimension].size() ) return; unsigned int dim0(options.dim0); unsigned int dim1(options.dim1); std::vector numberOfPixels; // number of pixels in the current slice that are equal to the active label int numberOfLabels = m_WorkingImage->GetNumberOfLabels(); numberOfPixels.resize( numberOfLabels ); typedef itk::Image ImageType; typedef itk::ImageRegionConstIteratorWithIndex< ImageType > IteratorType; IteratorType iter( input, input->GetLargestPossibleRegion() ); iter.GoToBegin(); typename IteratorType::IndexType index; while ( !iter.IsAtEnd() ) { index = iter.GetIndex(); int value = static_cast< int >(iter.Get()); ++ m_LabelCountInSlice[timeStep][dim0][index[0]][value]; ++ m_LabelCountInSlice[timeStep][dim1][index[1]][value]; ++ numberOfPixels[value]; ++iter; } for (unsigned int label=0; label void mitk::SliceBasedInterpolationController::ScanImageITKProcessing( itk::Image* input, unsigned int timeStep ) { typedef itk::ImageSliceConstIteratorWithIndex< itk::Image > IteratorType; IteratorType iter( input, input->GetLargestPossibleRegion() ); iter.SetFirstDirection(0); iter.SetSecondDirection(1); typename IteratorType::IndexType index; unsigned int x = 0; unsigned int y = 0; unsigned int z = 0; std::vector numberOfPixels; // number of pixels per slice that are equal to the active label int numberOfLabels = m_WorkingImage->GetNumberOfLabels(); numberOfPixels.resize( numberOfLabels ); iter.GoToBegin(); while ( !iter.IsAtEnd() ) { while ( !iter.IsAtEndOfSlice() ) { while ( !iter.IsAtEndOfLine() ) { index = iter.GetIndex(); x = index[0]; y = index[1]; z = index[2]; int value = static_cast( iter.Get() ); ++m_LabelCountInSlice[timeStep][0][x][value]; ++m_LabelCountInSlice[timeStep][1][y][value]; ++numberOfPixels[value]; ++iter; } iter.NextLine(); } for (unsigned int label = 0; label < numberOfLabels; ++label) m_LabelCountInSlice[timeStep][2][z][label] += numberOfPixels[label]; // clear label counter numberOfPixels.assign(numberOfLabels, 0); iter.NextSlice(); } } mitk::Image::Pointer mitk::SliceBasedInterpolationController::Interpolate(unsigned int sliceDimension, unsigned int sliceIndex, const mitk::PlaneGeometry* currentPlane, unsigned int timeStep ) { if (m_WorkingImage.IsNull()) return NULL; if (!currentPlane) return NULL; if ( timeStep >= m_LabelCountInSlice.size() ) return NULL; if ( sliceDimension > 2 ) return NULL; int upperLimit = m_LabelCountInSlice[timeStep][sliceDimension].size(); if ( sliceIndex >= upperLimit - 1 ) return NULL; // can't interpolate first and last slice if ( sliceIndex < 1 ) return NULL; int pixelValue = m_WorkingImage->GetActiveLabel()->GetValue(); // slice contains a segmentation, won't interpolate anything then if ( m_LabelCountInSlice[timeStep][sliceDimension][sliceIndex][pixelValue] > 0 ) return NULL; int lowerBound(0); int upperBound(0); bool bounds(false); for (lowerBound = sliceIndex - 1; /*lowerBound >= 0*/; --lowerBound) { if ( m_LabelCountInSlice[timeStep][sliceDimension][lowerBound][pixelValue] > 0 ) { bounds = true; break; } if (lowerBound == 0) break; } if (!bounds) return NULL; bounds = false; for (upperBound = sliceIndex + 1 ; upperBound < upperLimit; ++upperBound) { if ( m_LabelCountInSlice[timeStep][sliceDimension][upperBound][pixelValue] > 0 ) { bounds = true; break; } } if (!bounds) return NULL; // ok, we have found two neighboring slices with the active label // (and we made sure that the current slice does NOT contain the active label //Setting up the ExtractSliceFilter mitk::ExtractSliceFilter::Pointer extractor = ExtractSliceFilter::New(); extractor->SetInput(m_WorkingImage); extractor->SetTimeStep(timeStep); extractor->SetResliceTransformByGeometry( m_WorkingImage->GetTimeGeometry()->GetGeometryForTimeStep( timeStep ) ); extractor->SetVtkOutputRequest(false); //Reslicing the current plane extractor->SetWorldGeometry(currentPlane); extractor->Modified(); try { extractor->Update(); } catch(const std::exception &e) { MITK_ERROR<<"Error in 2D interpolation: " << e.what(); return NULL; } mitk::Image::Pointer resultImage = extractor->GetOutput(); resultImage->DisconnectPipeline(); //Creating PlaneGeometry for lower slice mitk::PlaneGeometry::Pointer reslicePlane = currentPlane->Clone(); //Transforming the current origin so that it matches the lower slice mitk::Point3D origin = currentPlane->GetOrigin(); m_WorkingImage->GetSlicedGeometry()->WorldToIndex(origin, origin); origin[sliceDimension] = lowerBound; m_WorkingImage->GetSlicedGeometry()->IndexToWorld(origin, origin); reslicePlane->SetOrigin(origin); //Extract the lower slice extractor->SetWorldGeometry(reslicePlane); extractor->Modified(); try { extractor->Update(); } catch(const std::exception &e) { MITK_ERROR<<"Error in 2D interpolation: " << e.what(); return NULL; } mitk::Image::Pointer lowerMITKSlice = extractor->GetOutput(); lowerMITKSlice->DisconnectPipeline(); //Transforming the current origin so that it matches the upper slice m_WorkingImage->GetSlicedGeometry()->WorldToIndex(origin, origin); origin[sliceDimension] = upperBound; m_WorkingImage->GetSlicedGeometry()->IndexToWorld(origin, origin); reslicePlane->SetOrigin(origin); //Extract the upper slice extractor->SetWorldGeometry(reslicePlane); extractor->Modified(); try { extractor->Update(); } catch(const std::exception &e) { MITK_ERROR<<"Error in 2D interpolation: " << e.what(); return NULL; } mitk::Image::Pointer upperMITKSlice = extractor->GetOutput(); upperMITKSlice->DisconnectPipeline(); if ( lowerMITKSlice.IsNull() || upperMITKSlice.IsNull() ) return NULL; // interpolation algorithm gets some inputs // two segmentations (guaranteed to be of the same data type, but no special data type guaranteed) // orientation (sliceDimension) of the segmentations // position of the two slices (sliceIndices) // one volume image (original patient image) // // interpolation algorithm can use e.g. itk::ImageSliceConstIteratorWithIndex to // inspect the original patient image at appropriate positions mitk::SegmentationInterpolationAlgorithm::Pointer algorithm = mitk::ShapeBasedInterpolationAlgorithm::New().GetPointer(); - //MLI TODO - //algorithm->Interpolate( lowerMITKSlice.GetPointer(), lowerBound, - // upperMITKSlice.GetPointer(), upperBound, - // sliceIndex, - // resultImage); + + algorithm->Interpolate( lowerMITKSlice.GetPointer(), lowerBound, + upperMITKSlice.GetPointer(), upperBound, + sliceIndex, + 0, + resultImage); return resultImage; } \ No newline at end of file diff --git a/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp b/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp index d7fd86f21a..6854968984 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkLabelSetWidget.cpp @@ -1,1248 +1,1244 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkLabelSetWidget.h" // mitk #include #include #include #include #include #include #include #include #include #include #include // Qmitk #include #include -// MLI Integration + #include // Qt #include #include #include #include #include #include #include #include -// MLI TODO #include // itk #include // todo: // berry //#include QmitkLabelSetWidget::QmitkLabelSetWidget(QWidget* parent) : QWidget(parent) , m_ToolManager(NULL) , m_DataStorage(NULL) , m_Completer(NULL) { m_Controls.setupUi(this); m_ColorSequenceRainbow.GoToBegin(); m_ToolManager = mitk::ToolManagerProvider::GetInstance()->GetToolManager(); assert(m_ToolManager); m_Controls.m_LabelSearchBox->setAlwaysShowClearIcon(true); m_Controls.m_LabelSearchBox->setShowSearchIcon(true); QStringList completionList; completionList << ""; m_Completer = new QCompleter(completionList, this); m_Completer->setCaseSensitivity(Qt::CaseInsensitive); m_Controls.m_LabelSearchBox->setCompleter(m_Completer); connect( m_Controls.m_LabelSearchBox, SIGNAL(returnPressed()), this, SLOT(OnSearchLabel()) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(labelListModified(const QStringList&)), this, SLOT( OnLabelListModified(const QStringList&)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(mergeLabel(int)), this, SLOT( OnMergeLabel(int)) ); QStringListModel* completeModel = static_cast (m_Completer->model()); completeModel->setStringList(GetLabelStringList()); m_Controls.m_LabelSearchBox->setEnabled(false); m_Controls.m_lblCaption->setText(""); InitializeTableWidget(); } QmitkLabelSetWidget::~QmitkLabelSetWidget() { } void QmitkLabelSetWidget::OnTableViewContextMenuRequested(const QPoint& pos) { QTableWidgetItem *itemAt = m_Controls.m_LabelSetTableWidget->itemAt(pos); //OnItemClicked(itemAt); if (!itemAt) return; int pixelValue = itemAt->data(Qt::UserRole).toInt(); QMenu* menu = new QMenu(m_Controls.m_LabelSetTableWidget); if (m_Controls.m_LabelSetTableWidget->selectedItems().size()>1) { QAction* mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge selection on current label", this ); mergeAction->setEnabled(true); QObject::connect( mergeAction, SIGNAL( triggered(bool) ), this, SLOT( OnMergeLabels(bool) ) ); menu->addAction(mergeAction); QAction* removeLabelsAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove selected labels", this ); removeLabelsAction->setEnabled(true); QObject::connect( removeLabelsAction, SIGNAL( triggered(bool) ), this, SLOT( OnRemoveLabels(bool) ) ); menu->addAction(removeLabelsAction); QAction* eraseLabelsAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase selected labels", this ); eraseLabelsAction->setEnabled(true); QObject::connect( eraseLabelsAction, SIGNAL( triggered(bool) ), this, SLOT( OnEraseLabels(bool) ) ); menu->addAction(eraseLabelsAction); QAction* combineAndCreateSurfaceAction = new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Combine and create a surface", this ); combineAndCreateSurfaceAction->setEnabled(true); QObject::connect( combineAndCreateSurfaceAction, SIGNAL( triggered(bool) ), this, SLOT( OnCombineAndCreateSurface(bool) ) ); menu->addAction(combineAndCreateSurfaceAction); QAction* createMasksAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create a mask for each selected label", this ); createMasksAction->setEnabled(true); QObject::connect( createMasksAction, SIGNAL( triggered(bool) ), this, SLOT( OnCreateMasks(bool) ) ); menu->addAction(createMasksAction); QAction* combineAndCreateMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Combine and create a mask", this ); combineAndCreateMaskAction->setEnabled(true); QObject::connect( combineAndCreateMaskAction, SIGNAL( triggered(bool) ), this, SLOT( OnCombineAndCreateMask(bool) ) ); menu->addAction(combineAndCreateMaskAction); } else { QAction* renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Rename...", this ); renameAction->setEnabled(true); QObject::connect( renameAction, SIGNAL( triggered(bool) ), this, SLOT( OnRenameLabel(bool) ) ); menu->addAction(renameAction); QAction* removeAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove...", this ); removeAction->setEnabled(true); QObject::connect( removeAction, SIGNAL( triggered(bool) ), this, SLOT( OnRemoveLabel(bool) ) ); menu->addAction(removeAction); QAction* eraseAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase...", this ); eraseAction->setEnabled(true); QObject::connect( eraseAction, SIGNAL( triggered(bool) ), this, SLOT( OnEraseLabel(bool) ) ); menu->addAction(eraseAction); QAction* mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge...", this ); mergeAction->setEnabled(true); QObject::connect( mergeAction, SIGNAL( triggered(bool) ), this, SLOT( OnMergeLabel(bool) ) ); menu->addAction(mergeAction); QAction* randomColorAction = new QAction(QIcon(":/Qmitk/RandomColor.png"), "Random color", this ); randomColorAction->setEnabled(true); QObject::connect( randomColorAction, SIGNAL( triggered(bool) ), this, SLOT( OnRandomColor(bool) ) ); menu->addAction(randomColorAction); QAction* viewOnlyAction = new QAction(QIcon(":/Qmitk/visible.png"), "View only", this ); viewOnlyAction->setEnabled(true); QObject::connect( viewOnlyAction, SIGNAL( triggered(bool) ), this, SLOT( OnSetOnlyActiveLabelVisible(bool) ) ); menu->addAction(viewOnlyAction); QAction* viewAllAction = new QAction(QIcon(":/Qmitk/visible.png"), "View all", this ); viewAllAction->setEnabled(true); QObject::connect( viewAllAction, SIGNAL( triggered(bool) ), this, SLOT( OnSetAllLabelsVisible(bool) ) ); menu->addAction(viewAllAction); QAction* hideAllAction = new QAction(QIcon(":/Qmitk/invisible.png"), "Hide all", this ); hideAllAction->setEnabled(true); QObject::connect( hideAllAction, SIGNAL( triggered(bool) ), this, SLOT( OnSetAllLabelsInvisible(bool) ) ); menu->addAction(hideAllAction); QAction* lockAllAction = new QAction(QIcon(":/Qmitk/lock.png"), "Lock all", this ); lockAllAction->setEnabled(true); QObject::connect( lockAllAction, SIGNAL( triggered(bool) ), this, SLOT( OnLockAllLabels(bool) ) ); menu->addAction(lockAllAction); QAction* unlockAllAction = new QAction(QIcon(":/Qmitk/unlock.png"), "Unlock all", this ); unlockAllAction->setEnabled(true); QObject::connect( unlockAllAction, SIGNAL( triggered(bool) ), this, SLOT( OnUnlockAllLabels(bool) ) ); menu->addAction(unlockAllAction); QAction* createSurfaceAction = new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Create surface", this ); createSurfaceAction->setEnabled(true); createSurfaceAction->setMenu(new QMenu()); QAction* tmp1 = createSurfaceAction->menu()->addAction(QString("Detailed")); QAction* tmp2 = createSurfaceAction->menu()->addAction(QString("Smoothed")); QObject::connect( tmp1, SIGNAL( triggered(bool) ), this, SLOT( OnCreateDetailedSurface(bool) ) ); QObject::connect( tmp2, SIGNAL( triggered(bool) ), this, SLOT( OnCreateSmoothedSurface(bool) ) ); menu->addAction(createSurfaceAction); QAction* createMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create mask", this ); createMaskAction->setEnabled(true); QObject::connect( createMaskAction, SIGNAL( triggered(bool) ), this, SLOT( OnCreateMask(bool) ) ); menu->addAction(createMaskAction); QAction* createCroppedMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create cropped mask", this ); createCroppedMaskAction->setEnabled(true); QObject::connect( createCroppedMaskAction, SIGNAL( triggered(bool) ), this, SLOT( OnCreateCroppedMask(bool) ) ); // QAction* importAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Import...", this ); // importAction->setEnabled(true); // QObject::connect( importAction, SIGNAL( triggered(bool) ), this, SLOT( OnImportSegmentationSession(bool) ) ); // menu->addAction(importAction); menu->addAction(createCroppedMaskAction); QSlider * opacitySlider = new QSlider; opacitySlider->setMinimum(0); opacitySlider->setMaximum(100); opacitySlider->setOrientation(Qt::Horizontal); QObject::connect( opacitySlider, SIGNAL( valueChanged(int) ), this, SLOT( OnOpacityChanged(int) ) ); QLabel* _OpacityLabel = new QLabel("Opacity: "); QVBoxLayout* _OpacityWidgetLayout = new QVBoxLayout; _OpacityWidgetLayout->setContentsMargins(4,4,4,4); _OpacityWidgetLayout->addWidget(_OpacityLabel); _OpacityWidgetLayout->addWidget(opacitySlider); QWidget* _OpacityWidget = new QWidget; _OpacityWidget->setLayout(_OpacityWidgetLayout); QWidgetAction * OpacityAction = new QWidgetAction(this); OpacityAction->setDefaultWidget(_OpacityWidget); // QObject::connect( m_OpacityAction, SIGNAL( changed() ), this, SLOT( OpacityActionChanged() ) ); opacitySlider->setValue(static_cast(GetWorkingImage()->GetLabel(pixelValue)->GetOpacity()*100)); menu->addAction(OpacityAction); } menu->popup(QCursor::pos()); } void QmitkLabelSetWidget::OnUnlockAllLabels(bool /*value*/) { GetWorkingImage()->GetLabelSet()->SetAllLabelsLocked(false); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnLockAllLabels(bool /*value*/) { GetWorkingImage()->GetLabelSet()->SetAllLabelsLocked(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnSetAllLabelsVisible(bool /*value*/) { GetWorkingImage()->GetLabelSet()->SetAllLabelsVisible(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnSetAllLabelsInvisible(bool /*value*/) { GetWorkingImage()->GetLabelSet()->SetAllLabelsVisible(false); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnSetOnlyActiveLabelVisible(bool /*value*/) { mitk::LabelSetImage * workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); workingImage->GetActiveLabelSet()->SetAllLabelsVisible(false); workingImage->GetLabel(pixelValue)->SetVisible(true); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); this->WaitCursorOn(); const mitk::Point3D& pos = workingImage->GetLabel(pixelValue)->GetCenterOfMassCoordinates(); this->WaitCursorOff(); if (pos.GetVnlVector().max_value() > 0.0) emit goToLabel(pos); UpdateAllTableWidgetItems(); } void QmitkLabelSetWidget::OnMergeLabel(bool /*value*/) { QmitkSearchLabelDialog dialog(this); dialog.setWindowTitle("Select a second label.."); dialog.SetLabelSuggestionList(GetLabelStringList()); int dialogReturnValue = dialog.exec(); if ( dialogReturnValue == QDialog::Rejected ) return; int pixelValue = -1; for(int i = 0 ; i < m_Controls.m_LabelSetTableWidget->columnCount();i++) { if( dialog.GetLabelSetWidgetTableCompleteWord() == QString( m_Controls.m_LabelSetTableWidget->item( i ,0)->text() ) ) pixelValue = m_Controls.m_LabelSetTableWidget->item(i ,0)->data(Qt::UserRole).toInt(); } if(pixelValue == -1 ) { MITK_INFO << "unknown label";; return; } GetWorkingImage()->MergeLabel(pixelValue); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnEraseLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to erase the contents of label \""; question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue)->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Erase label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { this->WaitCursorOn(); GetWorkingImage()->EraseLabel(pixelValue); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnRemoveLabel(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to remove label \""; question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue)->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Remove label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { this->WaitCursorOn(); GetWorkingImage()->GetActiveLabelSet()->RemoveLabel(pixelValue); GetWorkingImage()->EraseLabel(pixelValue); this->WaitCursorOff(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnRenameLabel(bool /*value*/) { QmitkNewSegmentationDialog dialog(this); dialog.setWindowTitle("Rename Label"); dialog.SetSuggestionList( m_OrganColors ); //MLI TODO //dialog.SetColor(GetWorkingImage()->GetActiveLabel()->GetColor()); //dialog.SetSegmentationName(GetWorkingImage()->GetActiveLabel()->GetName()); if ( dialog.exec() == QDialog::Rejected ) return; int pixelValue = GetWorkingImage()->GetActiveLabel()->GetValue(); GetWorkingImage()->GetLabel(pixelValue)->SetColor(dialog.GetColor()); GetWorkingImage()->GetLabel(pixelValue)->SetName(dialog.GetSegmentationName().toStdString()); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } void QmitkLabelSetWidget::OnCombineAndCreateMask( bool /*value*/ ) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ...to do... // } void QmitkLabelSetWidget::OnCreateMasks(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ..to do.. // } void QmitkLabelSetWidget::OnCombineAndCreateSurface(bool /*value*/) { m_Controls.m_LabelSetTableWidget->selectedRanges(); // ..to do.. // } void QmitkLabelSetWidget::OnEraseLabels(bool /*value*/) { QString question = "Do you really want to erase the selected labels?"; QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Erase selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if ( ranges.isEmpty() ) return; - std::vector VectorOfLablePixelValues; + std::vector VectorOfLablePixelValues; foreach (QTableWidgetSelectionRange a, ranges) for(int i = a.topRow(); i <= a.bottomRow(); i++) VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i,0)->data(Qt::UserRole).toInt()); this->WaitCursorOn(); - //MLI TODO - //GetWorkingImage()->EraseLabels(VectorOfLablePixelValues); + GetWorkingImage()->EraseLabels(VectorOfLablePixelValues); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnRemoveLabels(bool /*value*/) { QString question = "Do you really want to remove selected labels?"; QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if ( ranges.isEmpty() ) return; - std::vector VectorOfLablePixelValues; + std::vector VectorOfLablePixelValues; foreach (QTableWidgetSelectionRange a, ranges) for(int i = a.topRow(); i <= a.bottomRow(); i++) VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i,0)->data(Qt::UserRole).toInt()); this->WaitCursorOn(); - //MLI TODO - //GetWorkingImage()->RemoveLabels(VectorOfLablePixelValues); + GetWorkingImage()->RemoveLabels(VectorOfLablePixelValues); this->WaitCursorOff(); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnMergeLabels(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); QString question = "Do you really want to merge selected labels into \""; question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue)->GetName())); question.append("\"?"); QMessageBox::StandardButton answerButton = QMessageBox::question( this, "Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes); if (answerButton == QMessageBox::Yes) { QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if ( ranges.isEmpty() ) return; - std::vector VectorOfLablePixelValues; + std::vector VectorOfLablePixelValues; foreach (QTableWidgetSelectionRange a, ranges) for(int i = a.topRow(); i <= a.bottomRow(); i++) VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i,0)->data(Qt::UserRole).toInt()); this->WaitCursorOn(); int pixelValue = m_Controls.m_LabelSetTableWidget->item(m_Controls.m_LabelSetTableWidget->currentRow(),0)->data(Qt::UserRole).toInt(); - //MLI TODO - //GetWorkingImage()->MergeLabels(VectorOfLablePixelValues,pixelValue); + + GetWorkingImage()->MergeLabels(VectorOfLablePixelValues,pixelValue); this->WaitCursorOff(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnLockedButtonClicked() { int row; for(int i=0; irowCount(); i++) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i,LOCKED_COL)) { row = i; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { int pixelValue = m_Controls.m_LabelSetTableWidget->item(row,0)->data(Qt::UserRole).toInt(); GetWorkingImage()->GetLabel(pixelValue)->SetLocked(!GetWorkingImage()->GetLabel(pixelValue)->GetLocked() ); } } void QmitkLabelSetWidget::OnVisibleButtonClicked() { int row; for(int i=0; irowCount(); i++) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i,VISIBLE_COL)) { row = i; break; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { QTableWidgetItem * item = m_Controls.m_LabelSetTableWidget->item(row,0); OnItemClicked(item); int pixelValue = item->data(Qt::UserRole).toInt(); GetWorkingImage()->GetLabel(pixelValue)->SetVisible(!GetWorkingImage()->GetLabel(pixelValue)->GetVisible() ); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnColorButtonClicked() { int row; for(int i=0; irowCount(); i++) { if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i,COLOR_COL)) { row = i; } } if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount()) { int pixelValue = m_Controls.m_LabelSetTableWidget->item(row,0)->data(Qt::UserRole).toInt(); const mitk::Color& color = GetWorkingImage()->GetLabel(pixelValue)->GetColor(); QColor initial(color.GetRed()*255,color.GetGreen()*255,color.GetBlue()*255); QColor qcolor = QColorDialog::getColor(initial,0,QString("Change color")); if (!qcolor.isValid()) return; QPushButton* button = (QPushButton*) m_Controls.m_LabelSetTableWidget->cellWidget(row,COLOR_COL); if (!button) return; button->setAutoFillBackground(true); QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(qcolor.red())); styleSheet.append(","); styleSheet.append(QString::number(qcolor.green())); styleSheet.append(","); styleSheet.append(QString::number(qcolor.blue())); styleSheet.append(")"); button->setStyleSheet(styleSheet); mitk::Color newColor; newColor.SetRed(qcolor.red()/255.0); newColor.SetGreen(qcolor.green()/255.0); newColor.SetBlue(qcolor.blue()/255.0); GetWorkingImage()->GetLabel(pixelValue)->SetColor(newColor); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } } void QmitkLabelSetWidget::OnRandomColor(bool /*value*/) { int pixelValue = GetPixelValueOfSelectedItem(); GetWorkingImage()->GetLabel(pixelValue)->SetColor(m_ColorSequenceRainbow.GetNextColor() ); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } void QmitkLabelSetWidget::SetOrganColors(const QStringList& organColors) { m_OrganColors = organColors; } void QmitkLabelSetWidget::OnActiveLabelChanged(int pixelValue) { mitk::LabelSetImage* workingImage = GetWorkingImage(); assert(workingImage); workingImage->GetActiveLabelSet()->SetActiveLabel(pixelValue); //MITK_INFO << "Active Label set to << " << pixelValue; mitk::SurfaceBasedInterpolationController* interpolator = mitk::SurfaceBasedInterpolationController::GetInstance(); if (interpolator) interpolator->SetActiveLabel(pixelValue); } void QmitkLabelSetWidget::OnItemClicked(QTableWidgetItem *item) { if (!item) return; int pixelValue = item->data(Qt::UserRole).toInt(); QList ranges = m_Controls.m_LabelSetTableWidget->selectedRanges(); if(!ranges.empty() && ranges.back().rowCount() == 1) { SelectLabelByPixelValue(pixelValue); OnActiveLabelChanged(pixelValue); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkLabelSetWidget::OnItemDoubleClicked(QTableWidgetItem *item) { if (!item) return; int pixelValue = item->data(Qt::UserRole).toInt(); //OnItemClicked(item); <<-- Double click first call OnItemClicked WaitCursorOn(); mitk::LabelSetImage * workingImage = GetWorkingImage(); workingImage->UpdateCenterOfMass(pixelValue); const mitk::Point3D& pos = workingImage->GetLabel(pixelValue)->GetCenterOfMassCoordinates(); WaitCursorOff(); if (pos.GetVnlVector().max_value() > 0.0) emit goToLabel(pos); } void QmitkLabelSetWidget::SelectLabelByPixelValue(mitk::Label::PixelType pixelValue) { //MITK_INFO << "QmitkLabelSetWidget::SelectLabelByPixelValue " << pixelValue; if(!GetWorkingImage()->ExistLabel(pixelValue)) return; for(int row = 0 ; row < m_Controls.m_LabelSetTableWidget->rowCount(); row++) { if(m_Controls.m_LabelSetTableWidget->item(row,0)->data(Qt::UserRole).toInt() == pixelValue) { m_Controls.m_LabelSetTableWidget->clearSelection(); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_LabelSetTableWidget->selectRow(row); m_Controls.m_LabelSetTableWidget->scrollToItem(m_Controls.m_LabelSetTableWidget->item(row,0)); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); //SelectTableWidgetItem(m_Controls.m_LabelSetTableWidget->item(i,0)); //emit resetView(); //GetWorkingImage()->Modified(); return; } } } void QmitkLabelSetWidget::InsertTableWidgetItem(mitk::Label * label) { const mitk::Color& color = label->GetColor(); QTableWidget * tableWidget = m_Controls.m_LabelSetTableWidget; QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255)); styleSheet.append(")"); int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL)-2; QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth); QTableWidgetItem *nameItem = new QTableWidgetItem(text); nameItem->setTextAlignment(Qt::AlignCenter | Qt::AlignLeft); // ---!--- // IMPORTANT: ADD PIXELVALUE TO TABLEWIDGETITEM.DATA nameItem->setData(Qt::UserRole,QVariant(label->GetValue())); // ---!--- QPushButton * pbColor = new QPushButton(tableWidget); pbColor->setFixedSize(24,24); pbColor->setCheckable(false); pbColor->setAutoFillBackground(true); pbColor->setToolTip("Change label color"); pbColor->setStyleSheet(styleSheet); connect( pbColor, SIGNAL(clicked()), this, SLOT(OnColorButtonClicked()) ); QPushButton * pbLocked = new QPushButton(tableWidget); pbLocked->setFixedSize(24,24); QIcon * iconLocked = new QIcon(); iconLocked->addFile(QString::fromUtf8(":/Qmitk/lock.png"), QSize(), QIcon::Normal, QIcon::Off); iconLocked->addFile(QString::fromUtf8(":/Qmitk/unlock.png"), QSize(), QIcon::Normal, QIcon::On); pbLocked->setIcon(*iconLocked); pbLocked->setIconSize(QSize(24,24)); pbLocked->setCheckable(true); pbLocked->setToolTip("Lock/unlock label"); pbLocked->setChecked(!label->GetLocked()); connect( pbLocked, SIGNAL(clicked()), this, SLOT(OnLockedButtonClicked()) ); QPushButton * pbVisible = new QPushButton(tableWidget); pbVisible->setFixedSize(24,24); pbVisible->setAutoRepeat(false); QIcon * iconVisible = new QIcon(); iconVisible->addFile(QString::fromUtf8(":/Qmitk/visible.png"), QSize(), QIcon::Normal, QIcon::Off); iconVisible->addFile(QString::fromUtf8(":/Qmitk/invisible.png"), QSize(), QIcon::Normal, QIcon::On); pbVisible->setIcon(*iconVisible); pbVisible->setIconSize(QSize(24,24)); pbVisible->setCheckable(true); pbVisible->setToolTip("Show/hide label"); pbVisible->setChecked(!label->GetVisible()); connect( pbVisible, SIGNAL(clicked()), this, SLOT(OnVisibleButtonClicked()) ); int row = tableWidget->rowCount(); tableWidget->insertRow(row); tableWidget->setRowHeight(row,24); tableWidget->setItem(row, 0, nameItem ); tableWidget->setCellWidget(row, 1, pbLocked); tableWidget->setCellWidget(row, 2, pbColor); tableWidget->setCellWidget(row, 3, pbVisible); tableWidget->selectRow(row); //m_LabelSetImage->SetActiveLabel(label->GetPixelValue()); //m_ToolManager->WorkingDataModified.Send(); //emit activeLabelChanged(label->GetPixelValue()); if (row == 0) tableWidget->hideRow(row); // hide exterior label mitk::LabelSetImage * workingImage; if((workingImage = GetWorkingImage()) == NULL) return; } void QmitkLabelSetWidget::UpdateAllTableWidgetItems() { QTableWidget * tableWidget = m_Controls.m_LabelSetTableWidget; mitk::LabelSetImage * workingImage = GetWorkingImage(); if(!workingImage) return; // add all labels m_LabelStringList.clear(); for(int i = 0 ; i < tableWidget->rowCount(); i++) { UpdateTableWidgetItem(tableWidget->item(i,0)); m_LabelStringList.append( tableWidget->item(i,0)->text() ); } OnLabelListModified(m_LabelStringList); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::UpdateTableWidgetItem(QTableWidgetItem *item) { mitk::LabelSetImage * workingImage = GetWorkingImage(); mitk::Label * label = workingImage->GetLabel(item->data(Qt::UserRole).toInt()); const mitk::Color& color = label->GetColor(); QTableWidget * tableWidget = m_Controls.m_LabelSetTableWidget; QString styleSheet = "background-color:rgb("; styleSheet.append(QString::number(color[0]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[1]*255)); styleSheet.append(","); styleSheet.append(QString::number(color[2]*255)); styleSheet.append(")"); // Update text Label tableWdget->item(row,0) int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL)-2; QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth); item->setText(text); QPushButton * pbLocked = dynamic_cast(tableWidget->cellWidget(item->row(),1)); pbLocked->setChecked(!label->GetLocked()); QPushButton * pbColor = dynamic_cast(tableWidget->cellWidget(item->row(),2)); pbColor->setStyleSheet(styleSheet); QPushButton * pbVisible = dynamic_cast(tableWidget->cellWidget(item->row(),3)); pbVisible->setChecked(!label->GetVisible()); if (item->row() == 0)tableWidget->hideRow(item->row()); // hide exterior label } void QmitkLabelSetWidget::ResetAllTableWidgetItems() { QTableWidget * tableWidget = m_Controls.m_LabelSetTableWidget; // remove all rows while (tableWidget->rowCount()) tableWidget->removeRow( 0 ); mitk::LabelSetImage * workingImage = GetWorkingImage(); if(!workingImage) return; // add all labels m_LabelStringList.clear(); mitk::LabelSet::LabelContainerConstIteratorType it = workingImage->GetActiveLabelSet()->IteratorConstBegin(); mitk::LabelSet::LabelContainerConstIteratorType end = workingImage->GetActiveLabelSet()->IteratorConstEnd(); int pixelValue =-1; while (it != end) { InsertTableWidgetItem(it->second); if(GetWorkingImage()->GetActiveLabel() == it->second) // get active pixelValue = it->first; m_LabelStringList.append( QString(it->second->GetName().c_str()) ); it++; } SelectLabelByPixelValue(pixelValue); OnLabelListModified(m_LabelStringList); std::stringstream captionText; captionText << "Number of labels: " << workingImage->GetNumberOfLabels() - 1; m_Controls.m_lblCaption->setText(captionText.str().c_str()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } int QmitkLabelSetWidget::GetPixelValueOfSelectedItem() { if(m_Controls.m_LabelSetTableWidget->currentItem()) return m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt(); return -1; } QStringList & QmitkLabelSetWidget::GetLabelStringList() { return m_LabelStringList; } void QmitkLabelSetWidget::InitializeTableWidget() { QTableWidget * tableWidged = m_Controls.m_LabelSetTableWidget; tableWidged->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); tableWidged->setTabKeyNavigation(false); tableWidged->setAlternatingRowColors(false); tableWidged->setFocusPolicy(Qt::NoFocus); tableWidged->setColumnCount(4); tableWidged->resizeColumnToContents(NAME_COL); tableWidged->setColumnWidth(LOCKED_COL,25); tableWidged->setColumnWidth(COLOR_COL,25); tableWidged->setColumnWidth(VISIBLE_COL,25); tableWidged->horizontalHeader()->setResizeMode( 0, QHeaderView::Stretch ); tableWidged->setContextMenuPolicy(Qt::CustomContextMenu); tableWidged->horizontalHeader()->hide(); tableWidged->setSortingEnabled ( false ); tableWidged->verticalHeader()->hide(); tableWidged->setEditTriggers(QAbstractItemView::NoEditTriggers); tableWidged->setSelectionMode(QAbstractItemView::ExtendedSelection); tableWidged->setSelectionBehavior(QAbstractItemView::SelectRows); connect(tableWidged, SIGNAL(itemClicked(QTableWidgetItem *)), this, SLOT(OnItemClicked(QTableWidgetItem *))); connect(tableWidged, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this, SLOT(OnItemDoubleClicked(QTableWidgetItem *))); connect(tableWidged, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnTableViewContextMenuRequested(const QPoint&)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(activeLabelChanged(int)), this, SLOT(OnActiveLabelChanged(int)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(importSegmentation()), this, SLOT( OnImportSegmentation()) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(importLabeledImage()), this, SLOT( OnImportLabeledImage()) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(renameLabel(int, const mitk::Color&, const std::string&)), this, SLOT(OnRenameLabel(int, const mitk::Color&, const std::string&)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createSurface(int, bool)), this, SLOT(OnCreateSurface(int, bool)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(toggleOutline(bool)), this, SLOT(OnToggleOutline(bool)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(goToLabel(const mitk::Point3D&)), this, SIGNAL(goToLabel(const mitk::Point3D&)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(combineAndCreateSurface( const QList& )), // this, SLOT(OnCombineAndCreateSurface( const QList&)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createMask(int)), this, SLOT(OnCreateMask(int)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createCroppedMask(int)), this, SLOT(OnCreateCroppedMask(int)) ); //connect( m_Controls.m_LabelSetTableWidget, SIGNAL(combineAndCreateMask( const QList& )), // this, SLOT(OnCombineAndCreateMask( const QList&)) ); } void QmitkLabelSetWidget::OnOpacityChanged(int value) { int pixelValue = m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt(); float opacity = static_cast(value)/100.0f; GetWorkingImage()->GetLabel(pixelValue)->SetOpacity(opacity); GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue); } void QmitkLabelSetWidget::setEnabled(bool enabled) { QWidget::setEnabled(enabled); UpdateControls(); } void QmitkLabelSetWidget::SetDataStorage( mitk::DataStorage* storage ) { m_DataStorage = storage; } void QmitkLabelSetWidget::OnSearchLabel() { std::string text = m_Controls.m_LabelSearchBox->text().toStdString(); int pixelValue = -1; int row = -1; for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); i++){ if( m_Controls.m_LabelSetTableWidget->item(i,0)->text().toStdString().compare(text) == 0) { pixelValue = m_Controls.m_LabelSetTableWidget->item(i,0)->data(Qt::UserRole).toInt(); row = i; break; } } if(pixelValue == -1) return; GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue); QTableWidgetItem* nameItem = m_Controls.m_LabelSetTableWidget->item(row,NAME_COL); if (!nameItem) return; m_Controls.m_LabelSetTableWidget->clearSelection(); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.m_LabelSetTableWidget->selectRow(row); m_Controls.m_LabelSetTableWidget->scrollToItem(nameItem); m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); this->WaitCursorOn(); mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue)->GetCenterOfMassCoordinates(); - //MLI TODO - //m_ToolManager->WorkingDataModified.Send(); + m_ToolManager->WorkingDataChanged(); if (pos.GetVnlVector().max_value() > 0.0) emit goToLabel(pos); else { GetWorkingImage()->UpdateCenterOfMass(pixelValue); mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue)->GetCenterOfMassCoordinates(); emit goToLabel(pos); } this->WaitCursorOff(); } void QmitkLabelSetWidget::OnLabelListModified(const QStringList& list) { QStringListModel* completeModel = static_cast (m_Completer->model()); completeModel->setStringList(list); } mitk::LabelSetImage * QmitkLabelSetWidget::GetWorkingImage() { mitk::DataNode* workingNode = GetWorkingNode(); mitk::LabelSetImage* workingImage = dynamic_cast(workingNode->GetData()); assert(workingImage); return workingImage; } mitk::DataNode * QmitkLabelSetWidget::GetWorkingNode() { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); return workingNode; } void QmitkLabelSetWidget::UpdateControls() { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); bool hasWorkingData = (workingNode != NULL); m_Controls.m_LabelSetTableWidget->setEnabled(hasWorkingData); m_Controls.m_LabelSearchBox->setEnabled(hasWorkingData); if (!hasWorkingData) return; QStringListModel* completeModel = static_cast (m_Completer->model()); completeModel->setStringList(GetLabelStringList()); } void QmitkLabelSetWidget::OnCreateCroppedMask(bool) { m_ToolManager->ActivateTool(-1); mitk::DataNode* workingNode = GetWorkingNode(); mitk::LabelSetImage* workingImage = GetWorkingImage(); mitk::Image::Pointer maskImage; int pixelValue = GetPixelValueOfSelectedItem(); try { this->WaitCursorOn(); mitk::AutoCropImageFilter::Pointer cropFilter = mitk::AutoCropImageFilter::New(); cropFilter->SetInput( workingImage->CreateLabelMask(pixelValue) ); cropFilter->SetBackgroundValue( 0 ); cropFilter->SetMarginFactor(1.15); cropFilter->Update(); maskImage = cropFilter->GetOutput(); this->WaitCursorOff(); } catch ( mitk::Exception& e ) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } if (maskImage.IsNull()) { QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } mitk::DataNode::Pointer maskNode = mitk::DataNode::New(); std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName(); name += "-mask"; maskNode->SetName(name); maskNode->SetData(maskImage); maskNode->SetBoolProperty("binary", true); maskNode->SetBoolProperty("outline binary", true); maskNode->SetBoolProperty("outline binary shadow", true); maskNode->SetFloatProperty("outline width", 2.0); maskNode->SetColor(workingImage->GetLabel(pixelValue)->GetColor()); maskNode->SetOpacity(1.0); m_DataStorage->Add(maskNode, workingNode); } void QmitkLabelSetWidget::OnCreateMask(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode* workingNode = GetWorkingNode(); mitk::LabelSetImage* workingImage = GetWorkingImage(); mitk::Image::Pointer maskImage; int pixelValue = GetPixelValueOfSelectedItem(); try { this->WaitCursorOn(); maskImage = workingImage->CreateLabelMask(pixelValue); this->WaitCursorOff(); } catch ( mitk::Exception& e ) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } if (maskImage.IsNull()) { QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n"); return; } mitk::DataNode::Pointer maskNode = mitk::DataNode::New(); std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName(); name += "-mask"; maskNode->SetName(name); maskNode->SetData(maskImage); maskNode->SetBoolProperty("binary", true); maskNode->SetBoolProperty("outline binary", true); maskNode->SetBoolProperty("outline binary shadow", true); maskNode->SetFloatProperty("outline width", 2.0); maskNode->SetColor(workingImage->GetLabel(pixelValue)->GetColor()); maskNode->SetOpacity(1.0); m_DataStorage->Add(maskNode, workingNode); } void QmitkLabelSetWidget::OnToggleOutline(bool value) { mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); workingNode->SetBoolProperty( "labelset.contour.all", value); workingNode->GetData()->Modified(); // fixme: workaround to force data-type rendering (and not only property-type) mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::OnCreateSmoothedSurface(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode::Pointer workingNode = GetWorkingNode(); mitk::LabelSetImage* workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); mitk::LabelSetImageToSurfaceThreadedFilter::Pointer surfaceFilter = mitk::LabelSetImageToSurfaceThreadedFilter::New(); itk::SimpleMemberCommand::Pointer successCommand = itk::SimpleMemberCommand::New(); successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand); itk::SimpleMemberCommand::Pointer errorCommand = itk::SimpleMemberCommand::New(); errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand); mitk::DataNode::Pointer groupNode = workingNode; surfaceFilter->SetPointerParameter("Group node", groupNode); surfaceFilter->SetPointerParameter("Input", workingImage); surfaceFilter->SetParameter("RequestedLabel", pixelValue); surfaceFilter->SetParameter("Smooth", true); surfaceFilter->SetDataStorage( *m_DataStorage ); mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background..."); try { surfaceFilter->StartAlgorithm(); } catch ( mitk::Exception & e ) { MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Surface", "Could not create a surface mesh out of the selected label. See error log for details.\n"); } } void QmitkLabelSetWidget::OnCreateDetailedSurface(bool /*triggered*/) { m_ToolManager->ActivateTool(-1); mitk::DataNode::Pointer workingNode = GetWorkingNode(); mitk::LabelSetImage* workingImage = GetWorkingImage(); int pixelValue = GetPixelValueOfSelectedItem(); mitk::LabelSetImageToSurfaceThreadedFilter::Pointer surfaceFilter = mitk::LabelSetImageToSurfaceThreadedFilter::New(); itk::SimpleMemberCommand::Pointer successCommand = itk::SimpleMemberCommand::New(); successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand); itk::SimpleMemberCommand::Pointer errorCommand = itk::SimpleMemberCommand::New(); errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone); surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand); mitk::DataNode::Pointer groupNode = workingNode; surfaceFilter->SetPointerParameter("Group node", groupNode); surfaceFilter->SetPointerParameter("Input", workingImage); surfaceFilter->SetParameter("RequestedLabel", pixelValue); surfaceFilter->SetParameter("Smooth", false); surfaceFilter->SetDataStorage( *m_DataStorage ); mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background..."); try { surfaceFilter->StartAlgorithm(); } catch ( mitk::Exception & e ) { MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Create Surface", "Could not create a surface mesh out of the selected label. See error log for details.\n"); } } void QmitkLabelSetWidget::OnImportLabeledImage() { /* m_ToolManager->ActivateTool(-1); mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0); assert(referenceNode); // Ask the user for a list of files to open QStringList fileNames = QFileDialog::getOpenFileNames( this, "Open Image", m_LastFileOpenPath, mitk::CoreObjectFactory::GetInstance()->GetFileExtensions()); if (fileNames.empty()) return; try { this->WaitCursorOn(); mitk::Image::Pointer image = mitk::IOUtil::LoadImage( fileNames.front().toStdString() ); if (image.IsNull()) { this->WaitCursorOff(); QMessageBox::information(this, "Import Labeled Image", "Could not load the selected segmentation.\n"); return; } mitk::LabelSetImage::Pointer newImage = mitk::LabelSetImage::New(); newImage->InitializeByLabeledImage(image); this->WaitCursorOff(); mitk::DataNode::Pointer newNode = mitk::DataNode::New(); std::string newName = referenceNode->GetName(); newName += "-labels"; newNode->SetName(newName); newNode->SetData(newImage); m_DataStorage->Add(newNode, referenceNode); } catch (mitk::Exception & e) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Import Labeled Image", "Could not load the selected segmentation. See error log for details.\n"); return; } this->UpdateControls(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); */ } void QmitkLabelSetWidget::OnImportSegmentation() { /* m_ToolManager->ActivateTool(-1); mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0); assert(workingNode); mitk::LabelSetImage* workingImage = dynamic_cast( workingNode->GetData() ); assert(workingImage); std::string fileExtensions("Segmentation files (*.lset);;"); QString qfileName = QFileDialog::getOpenFileName(this, "Import Segmentation", m_LastFileOpenPath, fileExtensions.c_str() ); if (qfileName.isEmpty() ) return; mitk::NrrdLabelSetImageReader::Pointer reader = mitk::NrrdLabelSetImageReader::New(); reader->SetFileName(qfileName.toLatin1()); try { this->WaitCursorOn(); reader->Update(); mitk::LabelSetImage::Pointer newImage = reader->GetOutput(); workingImage->Concatenate(newImage); this->WaitCursorOff(); } catch ( mitk::Exception& e ) { this->WaitCursorOff(); MITK_ERROR << "Exception caught: " << e.GetDescription(); QMessageBox::information(this, "Import Segmentation", "Could not import the selected segmentation session.\n See error log for details.\n"); } */ mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkLabelSetWidget::WaitCursorOn() { QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); } void QmitkLabelSetWidget::WaitCursorOff() { this->RestoreOverrideCursor(); } void QmitkLabelSetWidget::RestoreOverrideCursor() { QApplication::restoreOverrideCursor(); } void QmitkLabelSetWidget::OnThreadedCalculationDone() { mitk::StatusBar::GetInstance()->Clear(); } \ No newline at end of file