bool LabelVolumeToSurfacesPluginInterface::CanRun() { IbisAPI *ibisAPI = GetIbisAPI(); Q_ASSERT(ibisAPI); ImageObject * image = ImageObject::SafeDownCast( ibisAPI->GetCurrentObject() ); if( image && image->IsLabelImage() ) return true; return false; }
void LabelVolumeToSurfacesPluginInterface::Run() { IbisAPI *ibisAPI = GetIbisAPI(); Q_ASSERT(ibisAPI); ImageObject * image = ImageObject::SafeDownCast( ibisAPI->GetCurrentObject() ); if( image && image->IsLabelImage() ) { // Get the range of labels double imageRange[2]; image->GetImageScalarRange( imageRange ); int minLabel = (int)floor( imageRange[ 0 ] ); if( minLabel == 0 ) minLabel = 1; // Usually, label 0 is a mask in minc files int maxLabel = (int)floor( imageRange[ 1 ] ); int numberOfLabels = maxLabel - minLabel + 1; // Compute the histogram to find out which labels really exist in the volume vtkImageAccumulate * histogram = vtkImageAccumulate::New(); histogram->SetInputData( image->GetImage() ); histogram->SetComponentExtent( 0, maxLabel, 0, 0, 0, 0 ); histogram->SetComponentOrigin( 0, 0, 0 ); histogram->SetComponentSpacing( 1, 1, 1 ); histogram->Update(); // Setup filters vtkDiscreteMarchingCubes * contourExtractor = vtkDiscreteMarchingCubes::New(); contourExtractor->SetInputData( image->GetImage() ); vtkTriangleFilter * triangleFilter = vtkTriangleFilter::New(); triangleFilter->SetInputConnection( contourExtractor->GetOutputPort() ); vtkStripper * stripper = vtkStripper::New(); stripper->SetInputConnection( triangleFilter->GetOutputPort() ); unsigned int smoothingIterations = 15; double passBand = 0.001; double featureAngle = 120.0; vtkWindowedSincPolyDataFilter * smoother = vtkWindowedSincPolyDataFilter::New(); smoother->SetInputConnection( stripper->GetOutputPort() ); smoother->SetNumberOfIterations(smoothingIterations); smoother->BoundarySmoothingOff(); smoother->FeatureEdgeSmoothingOff(); smoother->SetFeatureAngle(featureAngle); smoother->SetPassBand(passBand); smoother->NonManifoldSmoothingOn(); smoother->NormalizeCoordinatesOn(); IbisAPI *ibisAPI = GetIbisAPI(); Q_ASSERT(ibisAPI); QProgressDialog * pd = ibisAPI->StartProgress( 100, "Extracting surfaces..." ); QApplication::processEvents(); for( int i = minLabel; i <= maxLabel; ++i ) { // skip label if there is no voxel from this label double frequency = histogram->GetOutput()->GetPointData()->GetScalars()->GetTuple1(i); if( frequency == 0.0 ) continue; contourExtractor->SetValue( 0, i ); // Do the processing smoother->Update(); // Setup a PolyDataObject with output and add it to the scene vtkPolyData * outCopy = vtkPolyData::New(); outCopy->DeepCopy( smoother->GetOutput() ); PolyDataObject * polyDataObj = PolyDataObject::New(); QString objName = QString("Label %1").arg( i ); polyDataObj->SetName( objName ); polyDataObj->SetPolyData( outCopy ); if( i < 256 ) polyDataObj->SetColor( labelColors[i] ); ibisAPI->AddObject( polyDataObj, image ); // cleanup outCopy->Delete(); polyDataObj->Delete(); int progress = (int)( 100 * i / (double) numberOfLabels ); ibisAPI->UpdateProgress( pd, progress ); QApplication::processEvents(); } ibisAPI->StopProgress( pd ); // Cleanup contourExtractor->Delete(); triangleFilter->Delete(); stripper->Delete(); smoother->Delete(); histogram->Delete(); } else QMessageBox::warning( 0, "Error!", "Current object should be a label volume" ); }