void mitk::BinaryThresholdULTool::CreateNewSegmentationFromThreshold(DataNode* node) { if (node) { Image::Pointer feedBackImage = dynamic_cast<Image*>( m_ThresholdFeedbackNode->GetData() ); if (feedBackImage.IsNotNull()) { // create a new image of the same dimensions and smallest possible pixel type DataNode::Pointer emptySegmentation = GetTargetSegmentationNode(); if (emptySegmentation) { // actually perform a thresholding and ask for an organ type for (unsigned int timeStep = 0; timeStep < feedBackImage->GetTimeSteps(); ++timeStep) { try { ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New(); timeSelector->SetInput( feedBackImage ); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); Image::Pointer feedBackImage3D = timeSelector->GetOutput(); if (feedBackImage3D->GetDimension() == 2) { AccessFixedDimensionByItk_2( feedBackImage3D, ITKSetVolume, 2, dynamic_cast<Image*>(emptySegmentation->GetData()), timeStep ); } else { AccessFixedDimensionByItk_2( feedBackImage3D, ITKSetVolume, 3, dynamic_cast<Image*>(emptySegmentation->GetData()), timeStep ); } } catch(...) { Tool::ErrorMessage("Error accessing single time steps of the original image. Cannot create segmentation."); } } //since we are maybe working on a smaller image, pad it to the size of the original image if (m_OriginalImageNode.GetPointer() != m_NodeForThresholding.GetPointer()) { mitk::PadImageFilter::Pointer padFilter = mitk::PadImageFilter::New(); padFilter->SetInput(0, dynamic_cast<mitk::Image*> (emptySegmentation->GetData())); padFilter->SetInput(1, dynamic_cast<mitk::Image*> (m_OriginalImageNode->GetData())); padFilter->SetBinaryFilter(true); padFilter->SetUpperThreshold(1); padFilter->SetLowerThreshold(1); padFilter->Update(); emptySegmentation->SetData(padFilter->GetOutput()); } m_ToolManager->SetWorkingData( emptySegmentation ); m_ToolManager->GetWorkingData(0)->Modified(); } } } }
void job_test() { typedef itk::Image<int,3> Image; typedef itk::ImageFileReader<Image> Reader; // Read in the image (when debugging in VC++, it may be necessary to set the working directory to "$(TargetDir)"). std::cout << "Loading input image...\n"; Reader::Pointer reader = Reader::New(); reader->SetFileName("../resources/test.bmp"); reader->Update(); Image::Pointer image = reader->GetOutput(); // Create a DICOM volume (obviously not a proper one, as the image being read in is actually a greyscale one). DICOMVolume_Ptr volume(new DICOMVolume(image)); // Set the segmentation options. itk::Size<3> size = image->GetLargestPossibleRegion().GetSize(); WindowSettings windowSettings(40, 400); // dummy window settings CTSegmentationOptions options(30, CTSegmentationOptions::INPUTTYPE_HOUNSFIELD, size, 10, windowSettings); // Build the IPF. std::cout << "Building IPF...\n"; typedef CTIPFBuilder::IPF_Ptr IPF_Ptr; IPF_Ptr ipf; Job_Ptr job(new CTIPFBuilder(volume, options, ipf)); Job::execute_in_thread(job); while(!job->is_finished()); // Output the mosaic images for each of the partition forest layers. std::cout << "Outputting mosaic images...\n"; for(int i=0; i<=ipf->highest_layer(); ++i) { output_mosaic_image(ipf, i, size[0], size[1]); } }
//#################### HELPER FUNCTIONS #################### itk::Image<unsigned char,2>::Pointer make_mosaic_image(const boost::shared_ptr<const PartitionForest<CTImageLeafLayer,CTImageBranchLayer> >& ipf, int layerIndex, int width, int height) { typedef itk::Image<unsigned char,2> Image; typedef PartitionForest<CTImageLeafLayer,CTImageBranchLayer> IPF; Image::Pointer image = ITKImageUtil::make_image<unsigned char>(width, height); Image::IndexType index; int n = 0; for(index[1]=0; index[1]<height; ++index[1]) for(index[0]=0; index[0]<width; ++index[0]) { unsigned char mosaicValue; if(layerIndex > 0) { PFNodeID ancestor = ipf->ancestor_of(PFNodeID(0, n), layerIndex); mosaicValue = static_cast<unsigned char>(ipf->branch_properties(ancestor).mean_grey_value()); } else mosaicValue = ipf->leaf_properties(n).grey_value(); image->SetPixel(index, mosaicValue); ++n; } return image; }
bool CalculateSegmentationVolume::ReadyToRun() { Image::Pointer image; GetPointerParameter("Input", image); return image.IsNotNull() && GetGroupNode(); }
void mitk::SegTool2D::WriteBackSegmentationResult(std::vector<mitk::SegTool2D::SliceInformation> sliceList, bool writeSliceToVolume) { std::vector<mitk::Surface::Pointer> contourList; contourList.reserve(sliceList.size()); ImageToContourFilter::Pointer contourExtractor = ImageToContourFilter::New(); DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); Image* image = dynamic_cast<Image*>(workingNode->GetData()); mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput( image ); timeSelector->SetTimeNr( 0 ); timeSelector->SetChannelNr( 0 ); timeSelector->Update(); Image::Pointer dimRefImg = timeSelector->GetOutput(); for (unsigned int i = 0; i < sliceList.size(); ++i) { SliceInformation currentSliceInfo = sliceList.at(i); if(writeSliceToVolume) this->WriteSliceToVolume(currentSliceInfo); if (m_SurfaceInterpolationEnabled && dimRefImg->GetDimension() == 3) { currentSliceInfo.slice->DisconnectPipeline(); contourExtractor->SetInput(currentSliceInfo.slice); contourExtractor->Update(); mitk::Surface::Pointer contour = contourExtractor->GetOutput(); contour->DisconnectPipeline(); contourList.push_back(contour); } } mitk::SurfaceInterpolationController::GetInstance()->AddNewContours(contourList); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); }
bool CalculateSegmentationVolume::ThreadedUpdateFunction() { // get image Image::Pointer image; GetPointerParameter("Input", image); AccessFixedDimensionByItk(image.GetPointer(), ItkImageProcessing, 3); // some magic to call the correctly templated function (we only do 3D images here!) // consider single voxel volume Vector3D spacing = image->GetSlicedGeometry()->GetSpacing(); // spacing in mm float volumeML = (ScalarType)m_Volume * spacing[0] * spacing[1] * spacing[2] / 1000.0; // convert to ml DataNode *groupNode = GetGroupNode(); if (groupNode) { groupNode->SetProperty("volume", FloatProperty::New(volumeML)); groupNode->SetProperty("centerOfMass", Vector3DProperty::New(m_CenterOfMass)); groupNode->SetProperty("boundingBoxMinimum", Vector3DProperty::New(m_MinIndexOfBoundingBox)); groupNode->SetProperty("boundingBoxMaximum", Vector3DProperty::New(m_MaxIndexOfBoundingBox)); groupNode->SetProperty("showVolume", BoolProperty::New(true)); } return true; }
/* * What is the input requested region that is required to produce the output * requested region? By default, the largest possible region is always * required but this is overridden in many subclasses. For instance, for an * image processing filter where an output pixel is a simple function of an * input pixel, the input requested region will be set to the output * requested region. For an image processing filter where an output pixel is * a function of the pixels in a neighborhood of an input pixel, then the * input requested region will need to be larger than the output requested * region (to avoid introducing artificial boundary conditions). This * function should never request an input region that is outside the the * input largest possible region (i.e. implementations of this method should * crop the input requested region at the boundaries of the input largest * possible region). */ void mitk::ExtractImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); ImageToImageFilter::InputImagePointer input = const_cast< ImageToImageFilter::InputImageType* > ( this->GetInput() ); Image::Pointer output = this->GetOutput(); if (input->GetDimension() == 2) { input->SetRequestedRegionToLargestPossibleRegion(); return; } Image::RegionType requestedRegion; requestedRegion = output->GetRequestedRegion(); requestedRegion.SetIndex(0, 0); requestedRegion.SetIndex(1, 0); requestedRegion.SetIndex(2, 0); requestedRegion.SetSize(0, input->GetDimension(0)); requestedRegion.SetSize(1, input->GetDimension(1)); requestedRegion.SetSize(2, input->GetDimension(2)); requestedRegion.SetIndex( m_SliceDimension, m_SliceIndex ); // only one slice needed requestedRegion.SetSize( m_SliceDimension, 1 ); input->SetRequestedRegion( &requestedRegion ); }
void mitk::GeometryClipImageFilter::GenerateData() { Image::ConstPointer input = this->GetInput(); Image::Pointer output = this->GetOutput(); if((output->IsInitialized()==false) || (m_ClippingGeometry.IsNull())) return; const Geometry2D * clippingGeometryOfCurrentTimeStep = NULL; if(m_TimeSlicedClippingGeometry.IsNull()) { clippingGeometryOfCurrentTimeStep = dynamic_cast<const Geometry2D*>(m_ClippingGeometry.GetPointer()); } else { clippingGeometryOfCurrentTimeStep = dynamic_cast<const Geometry2D*>(m_TimeSlicedClippingGeometry->GetGeometry3D(0)); } if(clippingGeometryOfCurrentTimeStep == NULL) return; m_InputTimeSelector->SetInput(input); m_OutputTimeSelector->SetInput(this->GetOutput()); mitk::Image::RegionType outputRegion = output->GetRequestedRegion(); const mitk::TimeSlicedGeometry *outputTimeGeometry = output->GetTimeSlicedGeometry(); const mitk::TimeSlicedGeometry *inputTimeGeometry = input->GetTimeSlicedGeometry(); ScalarType timeInMS; int timestep=0; int tstart=outputRegion.GetIndex(3); int tmax=tstart+outputRegion.GetSize(3); int t; for(t=tstart;t<tmax;++t) { timeInMS = outputTimeGeometry->TimeStepToMS( t ); timestep = inputTimeGeometry->MSToTimeStep( timeInMS ); m_InputTimeSelector->SetTimeNr(timestep); m_InputTimeSelector->UpdateLargestPossibleRegion(); m_OutputTimeSelector->SetTimeNr(t); m_OutputTimeSelector->UpdateLargestPossibleRegion(); if(m_TimeSlicedClippingGeometry.IsNotNull()) { timestep = m_TimeSlicedClippingGeometry->MSToTimeStep( timeInMS ); if(m_TimeSlicedClippingGeometry->IsValidTime(timestep) == false) continue; clippingGeometryOfCurrentTimeStep = dynamic_cast<const Geometry2D*>(m_TimeSlicedClippingGeometry->GetGeometry3D(timestep)); } AccessByItk_2(m_InputTimeSelector->GetOutput(),_InternalComputeClippedImage,this,clippingGeometryOfCurrentTimeStep); } m_TimeOfHeaderInitialization.Modified(); }
static IntensityProfile::Pointer ComputeIntensityProfile(Image::Pointer image, itk::PolyLineParametricPath<3>::Pointer path) { IntensityProfile::Pointer intensityProfile = IntensityProfile::New(); itk::PolyLineParametricPath<3>::InputType input = path->StartOfInput(); BaseGeometry* imageGeometry = image->GetGeometry(); const PixelType pixelType = image->GetPixelType(); IntensityProfile::MeasurementVectorType measurementVector; itk::PolyLineParametricPath<3>::OffsetType offset; Point3D worldPoint; itk::Index<3> index; do { imageGeometry->IndexToWorld(path->Evaluate(input), worldPoint); imageGeometry->WorldToIndex(worldPoint, index); mitkPixelTypeMultiplex3(ReadPixel, pixelType, image, index, measurementVector.GetDataPointer()); intensityProfile->PushBack(measurementVector); offset = path->IncrementInput(input); } while ((offset[0] | offset[1] | offset[2]) != 0); return intensityProfile; }
ImageBinary::Pointer label2mask(Image::Pointer label, unsigned int element) { ImageBinary::Pointer mask = ImageBinary::New(); Image::RegionType region = label->GetLargestPossibleRegion(); mask->SetRegions(region); mask->Allocate(); mask->FillBuffer(0); ConstIterator iterator_label(label, label->GetLargestPossibleRegion()); IteratorBinary iterator_mask(mask, mask->GetLargestPossibleRegion()); try { while(!iterator_label.IsAtEnd()) { if(iterator_label.Get() == element && element || iterator_label.Get() != 0 && !element) iterator_mask.Set(1); ++iterator_label; ++iterator_mask; } } catch(itk::ExceptionObject & err) { std::cerr<<"Exception caught, outside bounds using iterators"<<std::endl; std::cerr<<err<<std::endl; } return mask; }
void mitk::SegTool2D::UpdateSurfaceInterpolation(const Image *slice, const Image *workingImage, const PlaneGeometry *plane, bool detectIntersection) { if (!m_SurfaceInterpolationEnabled) return; ImageToContourFilter::Pointer contourExtractor = ImageToContourFilter::New(); mitk::Surface::Pointer contour; if (detectIntersection) { // Test whether there is something to extract or whether the slice just contains intersections of others mitk::Image::Pointer slice2 = slice->Clone(); mitk::MorphologicalOperations::Erode(slice2, 2, mitk::MorphologicalOperations::Ball); contourExtractor->SetInput(slice2); contourExtractor->Update(); contour = contourExtractor->GetOutput(); if (contour->GetVtkPolyData()->GetNumberOfPoints() == 0) { // Remove contour! mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo; contourInfo.contourNormal = plane->GetNormal(); contourInfo.contourPoint = plane->GetOrigin(); mitk::SurfaceInterpolationController::GetInstance()->RemoveContour(contourInfo); return; } } contourExtractor->SetInput(slice); contourExtractor->Update(); contour = contourExtractor->GetOutput(); mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(workingImage); timeSelector->SetTimeNr(0); timeSelector->SetChannelNr(0); timeSelector->Update(); Image::Pointer dimRefImg = timeSelector->GetOutput(); if (contour->GetVtkPolyData()->GetNumberOfPoints() != 0 && dimRefImg->GetDimension() == 3) { mitk::SurfaceInterpolationController::GetInstance()->AddNewContour(contour); contour->DisconnectPipeline(); } else { // Remove contour! mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo; contourInfo.contourNormal = plane->GetNormal(); contourInfo.contourPoint = plane->GetOrigin(); mitk::SurfaceInterpolationController::GetInstance()->RemoveContour(contourInfo); } }
void mitk::BinaryThresholdULTool::CreateNewSegmentationFromThreshold(DataNode* node, const std::string& organName, const Color& color) { if (node) { Image::Pointer image = dynamic_cast<Image*>( m_NodeForThresholding->GetData() ); if (image.IsNotNull()) { // create a new image of the same dimensions and smallest possible pixel type DataNode::Pointer emptySegmentation = Tool::CreateEmptySegmentationNode( image, organName, color ); if (emptySegmentation) { // actually perform a thresholding and ask for an organ type for (unsigned int timeStep = 0; timeStep < image->GetTimeSteps(); ++timeStep) { try { ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New(); timeSelector->SetInput( image ); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); Image::Pointer image3D = timeSelector->GetOutput(); AccessFixedDimensionByItk_2( image3D, ITKThresholding, 3, dynamic_cast<Image*>(emptySegmentation->GetData()), timeStep ); } catch(...) { Tool::ErrorMessage("Error accessing single time steps of the original image. Cannot create segmentation."); } } //since we are maybe working on a smaller image, pad it to the size of the original image if (m_OriginalImageNode.GetPointer() != m_NodeForThresholding.GetPointer()) { mitk::PadImageFilter::Pointer padFilter = mitk::PadImageFilter::New(); padFilter->SetInput(0, dynamic_cast<mitk::Image*> (emptySegmentation->GetData())); padFilter->SetInput(1, dynamic_cast<mitk::Image*> (m_OriginalImageNode->GetData())); padFilter->SetBinaryFilter(true); padFilter->SetUpperThreshold(1); padFilter->SetLowerThreshold(1); padFilter->Update(); emptySegmentation->SetData(padFilter->GetOutput()); } if (DataStorage* ds = m_ToolManager->GetDataStorage()) { ds->Add( emptySegmentation, m_OriginalImageNode ); } m_ToolManager->SetWorkingData( emptySegmentation ); } } } }
bool SegmentationSink::ReadyToRun() { Image::Pointer image; GetPointerParameter("Input", image); DataNode::Pointer groupNode; GetPointerParameter("Group node", groupNode); return image.IsNotNull() && groupNode.IsNotNull(); }
mitk::Image::Pointer mitk::CompressedImageContainer::GetImage() { if (m_ByteBuffers.empty()) return nullptr; // uncompress image data, create an Image Image::Pointer image = Image::New(); unsigned int dims[20]; // more than 20 dimensions and bang for (unsigned int dim = 0; dim < m_ImageDimension; ++dim) dims[dim] = m_ImageDimensions[dim]; image->Initialize(*m_PixelType, m_ImageDimension, dims); // this IS needed, right ?? But it does allocate memory -> // does create one big lump of memory (also in windows) unsigned int timeStep(0); for (auto iter = m_ByteBuffers.begin(); iter != m_ByteBuffers.end(); ++iter, ++timeStep) { ImageReadAccessor imgAcc(image, image->GetVolumeData(timeStep)); auto *dest((unsigned char *)imgAcc.GetData()); ::uLongf destLen(m_OneTimeStepImageSizeInBytes); ::Bytef *source(iter->first); ::uLongf sourceLen(iter->second); int zlibRetVal = ::uncompress(dest, &destLen, source, sourceLen); if (itk::Object::GetDebug()) { if (zlibRetVal == Z_OK) { MITK_INFO << "Success, destLen now " << destLen << " bytes" << std::endl; } else { switch (zlibRetVal) { case Z_DATA_ERROR: MITK_ERROR << "compressed data corrupted" << std::endl; break; case Z_MEM_ERROR: MITK_ERROR << "not enough memory" << std::endl; break; case Z_BUF_ERROR: MITK_ERROR << "output buffer too small" << std::endl; break; default: MITK_ERROR << "other, unspecified error" << std::endl; break; } } } } image->SetGeometry(m_ImageGeometry); image->Modified(); return image; }
/* * Generate the information decribing the output data. The default * implementation of this method will copy information from the input to the * output. A filter may override this method if its output will have different * information than its input. For instance, a filter that shrinks an image will * need to provide an implementation for this method that changes the spacing of * the pixels. Such filters should call their superclass' implementation of this * method prior to changing the information values they need (i.e. * GenerateOutputInformation() should call * Superclass::GenerateOutputInformation() prior to changing the information. */ void mitk::ExtractImageFilter::GenerateOutputInformation() { Image::Pointer output = this->GetOutput(); Image::ConstPointer input = this->GetInput(); if (input.IsNull()) return; if ( m_SliceDimension >= input->GetDimension() && input->GetDimension() != 2 ) { MITK_ERROR << "mitk::ExtractImageFilter:GenerateOutputInformation m_SliceDimension == " << m_SliceDimension << " makes no sense with an " << input->GetDimension() << "D image." << std::endl; itkExceptionMacro("This is not a sensible value for m_SliceDimension."); return; } unsigned int sliceDimension( m_SliceDimension ); if ( input->GetDimension() == 2) { sliceDimension = 2; } unsigned int tmpDimensions[2]; switch ( sliceDimension ) { default: case 2: // orientation = PlaneGeometry::Axial; tmpDimensions[0] = input->GetDimension(0); tmpDimensions[1] = input->GetDimension(1); break; case 1: // orientation = PlaneGeometry::Frontal; tmpDimensions[0] = input->GetDimension(0); tmpDimensions[1] = input->GetDimension(2); break; case 0: // orientation = PlaneGeometry::Sagittal; tmpDimensions[0] = input->GetDimension(1); tmpDimensions[1] = input->GetDimension(2); break; } output->Initialize(input->GetPixelType(), 2, tmpDimensions, 1 /*input->GetNumberOfChannels()*/); // initialize the spacing of the output /* Vector3D spacing = input->GetSlicedGeometry()->GetSpacing(); if(input->GetDimension()>=2) spacing[2]=spacing[1]; else spacing[2] = 1.0; output->GetSlicedGeometry()->SetSpacing(spacing); */ output->SetPropertyList(input->GetPropertyList()->Clone()); }
void mitk::CollectionGrayOpening::PerformGrayOpening(mitk::DataCollection *dataCollection, std::string name, std::string suffix) { for (size_t patient = 0; patient < dataCollection->Size(); ++patient) { DataCollection *dataPatient = dynamic_cast<DataCollection *>(dataCollection->GetData(patient).GetPointer()); if (dataPatient == nullptr) MITK_ERROR << "PerformGrayOpening - Structure of DataCollection is invalid at patient level. Data inconsistent!"; if (dataPatient->Size() == 0) MITK_ERROR << "Empty Patient Collective. Probably Fatal."; for (size_t timeStep = 0; timeStep < dataPatient->Size(); ++timeStep) { DataCollection *dataTimeStep = dynamic_cast<DataCollection *>(dataPatient->GetData(timeStep).GetPointer()); if (dataTimeStep == nullptr) MITK_ERROR << "DilateBinaryByName- Structure of DataCollection is invalid at time step level. Data inconsistent!"; // BinaryImage::Pointer itkImage = BinaryImage::New(); ImageType::Pointer itkImage = ImageType::New(); Image::Pointer tmp = dataTimeStep->GetMitkImage(name).GetPointer(); if (tmp.IsNull()) MITK_ERROR << "null"; CastToItkImage(tmp, itkImage); if (itkImage.IsNull()) MITK_ERROR << "Image " << name << " does not exist. Fatal."; typedef itk::FlatStructuringElement<3> StructuringElementType; StructuringElementType::RadiusType elementRadius; elementRadius.Fill(1); elementRadius[2] = 0; StructuringElementType structuringElement = StructuringElementType::Box(elementRadius); typedef itk::GrayscaleMorphologicalOpeningImageFilter<ImageType, ImageType, StructuringElementType> DilateImageFilterType; DilateImageFilterType::Pointer dilateFilter0 = DilateImageFilterType::New(); dilateFilter0->SetInput(itkImage); dilateFilter0->SetKernel(structuringElement); dilateFilter0->Update(); DilateImageFilterType::Pointer dilateFilter1 = DilateImageFilterType::New(); dilateFilter1->SetInput(dilateFilter0->GetOutput()); dilateFilter1->SetKernel(structuringElement); dilateFilter1->Update(); Image::Pointer dil = GrabItkImageMemory(dilateFilter1->GetOutput()); dataTimeStep->AddData(dil.GetPointer(), name + suffix, ""); } } }
void mitk::SetRegionTool::OnMouseReleased(StateMachineAction *, InteractionEvent *interactionEvent) { auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent); if (!positionEvent) return; assert(positionEvent->GetSender()->GetRenderWindow()); // 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's // working image corresponds to that FeedbackContourTool::SetFeedbackContourVisible(false); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); int timeStep = positionEvent->GetSender()->GetTimeStep(); DataNode *workingNode(m_ToolManager->GetWorkingData(0)); if (!workingNode) return; auto *image = dynamic_cast<Image *>(workingNode->GetData()); const PlaneGeometry *planeGeometry((positionEvent->GetSender()->GetCurrentWorldPlaneGeometry())); if (!image || !planeGeometry) return; Image::Pointer slice = FeedbackContourTool::GetAffectedImageSliceAs2DImage(positionEvent, image); if (slice.IsNull()) { MITK_ERROR << "Unable to extract slice." << std::endl; return; } ContourModel *feedbackContour(FeedbackContourTool::GetFeedbackContour()); ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, false, false); // false: don't add 0.5 (done by FillContourInSlice) // false: don't constrain the contour to the image's inside if (projectedContour.IsNull()) return; auto *labelImage = dynamic_cast<LabelSetImage *>(image); int activeColor = 1; if (labelImage != nullptr) { activeColor = labelImage->GetActiveLabel()->GetValue(); } mitk::ContourModelUtils::FillContourInSlice( projectedContour, timeStep, slice, image, m_PaintingPixelValue * activeColor); this->WriteBackSegmentationResult(positionEvent, slice); }
mitk::Image::Pointer mitk::VolumeDataVtkMapper3D::GetMask() { if (this->m_Mask) { Image::Pointer mask = Image::New(); mask->Initialize(this->m_Mask); mask->SetImportVolume(this->m_Mask->GetScalarPointer(), 0, 0, Image::ReferenceMemory); mask->SetGeometry(this->GetInput()->GetGeometry()); return mask; } return 0; }
bool ShowSegmentationAsSurface::ReadyToRun() { try { Image::Pointer image; GetPointerParameter("Input", image); return image.IsNotNull() && GetGroupNode(); } catch (std::invalid_argument &) { return false; } }
void mitk::BinaryThresholdTool::SetupPreviewNode() { if (m_NodeForThresholding.IsNotNull()) { Image::Pointer image = dynamic_cast<Image*>(m_NodeForThresholding->GetData()); Image::Pointer originalImage = dynamic_cast<Image*> (m_OriginalImageNode->GetData()); if (image.IsNotNull()) { mitk::Image* workingimage = dynamic_cast<mitk::Image*>(m_ToolManager->GetWorkingData(0)->GetData()); if (workingimage) { m_ThresholdFeedbackNode->SetData(workingimage->Clone()); //Let's paint the feedback node green... mitk::LabelSetImage::Pointer previewImage = dynamic_cast<mitk::LabelSetImage*> (m_ThresholdFeedbackNode->GetData()); itk::RGBPixel<float> pixel; pixel[0] = 0.0f; pixel[1] = 1.0f; pixel[2] = 0.0f; previewImage->GetActiveLabel()->SetColor(pixel); previewImage->GetActiveLabelSet()->UpdateLookupTable(previewImage->GetActiveLabel()->GetValue()); } else m_ThresholdFeedbackNode->SetData(mitk::Image::New()); int layer(50); m_NodeForThresholding->GetIntProperty("layer", layer); m_ThresholdFeedbackNode->SetIntProperty("layer", layer + 1); if (DataStorage* ds = m_ToolManager->GetDataStorage()) { if (!ds->Exists(m_ThresholdFeedbackNode)) ds->Add(m_ThresholdFeedbackNode, m_OriginalImageNode); } if (image.GetPointer() == originalImage.GetPointer()) { Image::StatisticsHolderPointer statistics = originalImage->GetStatistics(); m_SensibleMinimumThresholdValue = static_cast<double>(statistics->GetScalarValueMin()); m_SensibleMaximumThresholdValue = static_cast<double>(statistics->GetScalarValueMax()); } if ((originalImage->GetPixelType().GetPixelType() == itk::ImageIOBase::SCALAR) && (originalImage->GetPixelType().GetComponentType() == itk::ImageIOBase::FLOAT || originalImage->GetPixelType().GetComponentType() == itk::ImageIOBase::DOUBLE)) m_IsFloatImage = true; else m_IsFloatImage = false; m_CurrentThresholdValue = (m_SensibleMaximumThresholdValue + m_SensibleMinimumThresholdValue) / 2.0; IntervalBordersChanged.Send(m_SensibleMinimumThresholdValue, m_SensibleMaximumThresholdValue, m_IsFloatImage); ThresholdingValueChanged.Send(m_CurrentThresholdValue); } } }
mitk::Image::Pointer mitk::SegTool2D::GetAffectedImageSliceAs2DImage(const PlaneGeometry* planeGeometry, const Image* image, unsigned int timeStep) { if ( !image || !planeGeometry ) return NULL; //Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk reslicer vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New(); //set to false to extract a slice reslice->SetOverwriteMode(false); reslice->Modified(); //use ExtractSliceFilter with our specific vtkImageReslice for overwriting and extracting mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice); extractor->SetInput( image ); extractor->SetTimeStep( timeStep ); extractor->SetWorldGeometry( planeGeometry ); extractor->SetVtkOutputRequest(false); extractor->SetResliceTransformByGeometry( image->GetTimeGeometry()->GetGeometryForTimeStep( timeStep ) ); extractor->Modified(); extractor->Update(); Image::Pointer slice = extractor->GetOutput(); /*============= BEGIN undo feature block ========================*/ //specify the undo operation with the non edited slice m_undoOperation = new DiffSliceOperation(const_cast<mitk::Image*>(image), extractor->GetVtkOutput(), slice->GetGeometry(), timeStep, const_cast<mitk::PlaneGeometry*>(planeGeometry)); /*============= END undo feature block ========================*/ return slice; }
float get_mean(Image::Pointer im) { ConstIterator it; it = ConstIterator(im, im->GetLargestPossibleRegion()); float mean = 0, N=0; try { while(!it.IsAtEnd()) { if(it.Get()!=0) { mean = N/(N+1)*mean + it.Get()/(N+1); ++N; } ++it; } } catch( itk::ExceptionObject & err) { std::cout<<"Error calculating mean, iterator error"<<std::endl; std::cout<<err<<std::endl; } return mean; }
/** Close the contour, project it to the image slice and fill it in 2D. */ bool mitk::ContourTool::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent ) { // 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's working image corresponds to that FeedbackContourTool::SetFeedbackContourVisible(false); mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent ); //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); if (!positionEvent) return false; assert( positionEvent->GetSender()->GetRenderWindow() ); mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() ); DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); if (!workingNode) return false; Image* image = dynamic_cast<Image*>(workingNode->GetData()); const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) ); if ( !image || !planeGeometry ) return false; const AbstractTransformGeometry* abstractTransformGeometry( dynamic_cast<const AbstractTransformGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) ); if ( !image || abstractTransformGeometry ) return false; // 2. Slice is known, now we try to get it as a 2D image and project the contour into index coordinates of this slice Image::Pointer slice = SegTool2D::GetAffectedImageSliceAs2DImage( positionEvent, image ); if ( slice.IsNull() ) { MITK_ERROR << "Unable to extract slice." << std::endl; return false; } ContourModel* feedbackContour = FeedbackContourTool::GetFeedbackContour(); ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, true, false ); // true: actually no idea why this is neccessary, but it works :-( if (projectedContour.IsNull()) return false; int timestep = positionEvent->GetSender()->GetTimeStep(); FeedbackContourTool::FillContourInSlice( projectedContour, timestep, slice, m_PaintingPixelValue ); this->WriteBackSegmentationResult(positionEvent, slice); // 4. Make sure the result is drawn again --> is visible then. assert( positionEvent->GetSender()->GetRenderWindow() ); return true; }
Image::Pointer WorkbenchUtils::addPadding(Image::Pointer image, Axis axis, bool append, int numberOfSlices, float paddingPixelValue) { // AccessByItk is a precompiler macro that sets up the instantiations for all possible template combinations. This will directly // reflect in the compile time and required memory since functions for all permutations of PixelTypes and Dimensions will be created. // The amount of parameters is not limited. However, a return is not possible. So we work with an out parameter: Image::Pointer returnImage = Image::New(); AccessByItk_n(image.GetPointer(), addPaddingItk, (axis, append, numberOfSlices, paddingPixelValue, returnImage)); return returnImage; }
void mitk::ImageTimeSelector::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); ImageToImageFilter::InputImagePointer input = const_cast< mitk::ImageToImageFilter::InputImageType * > ( this->GetInput() ); Image::Pointer output = this->GetOutput(); Image::RegionType requestedRegion; requestedRegion = output->GetRequestedRegion(); requestedRegion.SetIndex(3, m_TimeNr); requestedRegion.SetIndex(4, m_ChannelNr); requestedRegion.SetSize(3, 1); requestedRegion.SetSize(4, 1); input->SetRequestedRegion( & requestedRegion ); }
void mitk::ContourUtils::FillContourInSlice( ContourModel* projectedContour, unsigned int timeStep, Image* sliceImage, int paintingPixelValue ) { // 1. Use ipSegmentation to draw a filled(!) contour into a new 8 bit 2D image, which will later be copied back to the slice. // We don't work on the "real" working data, because ipSegmentation would restrict us to 8 bit images // convert the projected contour into a ipSegmentation format mitkIpInt4_t* picContour = new mitkIpInt4_t[2 * projectedContour->GetNumberOfVertices(timeStep)]; unsigned int index(0); ContourModel::VertexIterator iter = projectedContour->Begin(timeStep); ContourModel::VertexIterator end = projectedContour->End(timeStep); while( iter != end) { picContour[ 2 * index + 0 ] = static_cast<mitkIpInt4_t>( (*iter)->Coordinates[0] + 1.0 ); // +0.5 wahrscheinlich richtiger picContour[ 2 * index + 1 ] = static_cast<mitkIpInt4_t>( (*iter)->Coordinates[1] + 1.0 ); //MITK_INFO << "mitk 2d [" << (*iter)[0] << ", " << (*iter)[1] << "] pic [" << picContour[ 2*index+0] << ", " << picContour[ 2*index+1] << "]"; iter++; index++; } assert( sliceImage->GetSliceData() ); mitkIpPicDescriptor* originalPicSlice = mitkIpPicNew(); CastToIpPicDescriptor( sliceImage, originalPicSlice); mitkIpPicDescriptor* picSlice = ipMITKSegmentationNew( originalPicSlice ); ipMITKSegmentationClear( picSlice ); assert( originalPicSlice && picSlice ); // here comes the actual contour filling algorithm (from ipSegmentation/Graphics Gems) ipMITKSegmentationCombineRegion ( picSlice, picContour, projectedContour->GetNumberOfVertices(timeStep), NULL, IPSEGMENTATION_OR, 1); // set to 1 delete[] picContour; // 2. Copy the filled contour to the working data slice // copy all pixels that are non-zero to the original image (not caring for the actual type of the working image). perhaps make the replace value a parameter ( -> general painting tool ). // make the pic slice an mitk/itk image (as little ipPic code as possible), call a templated method with accessbyitk, iterate over the original and the modified slice Image::Pointer ipsegmentationModifiedSlice = Image::New(); ipsegmentationModifiedSlice->Initialize( CastToImageDescriptor( picSlice ) ); ipsegmentationModifiedSlice->SetSlice( picSlice->data ); AccessFixedDimensionByItk_2( sliceImage, ItkCopyFilledContourToSlice, 2, ipsegmentationModifiedSlice, paintingPixelValue ); ipsegmentationModifiedSlice = NULL; // free MITK header information ipMITKSegmentationFree( picSlice ); // free actual memory }
bool mitk::SetRegionTool::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent ) { // 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's working image corresponds to that FeedbackContourTool::SetFeedbackContourVisible(false); mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent ); if (!positionEvent) return false; assert( positionEvent->GetSender()->GetRenderWindow() ); mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow()); int timeStep = positionEvent->GetSender()->GetTimeStep(); if (!m_FillContour && !m_StatusFillWholeSlice) return true; DataNode* workingNode( m_ToolManager->GetWorkingData(0) ); if (!workingNode) return false; Image* image = dynamic_cast<Image*>(workingNode->GetData()); const AbstractTransformGeometry* abstractTransformGeometry( dynamic_cast<const AbstractTransformGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) ); const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) ); if ( !image || !planeGeometry || abstractTransformGeometry ) return false; Image::Pointer slice = FeedbackContourTool::GetAffectedImageSliceAs2DImage( positionEvent, image ); if ( slice.IsNull() ) { MITK_ERROR << "Unable to extract slice." << std::endl; return false; } ContourModel* feedbackContour( FeedbackContourTool::GetFeedbackContour() ); ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, false, false ); // false: don't add 0.5 (done by FillContourInSlice) // false: don't constrain the contour to the image's inside if (projectedContour.IsNull()) return false; FeedbackContourTool::FillContourInSlice( projectedContour, timeStep, slice, m_PaintingPixelValue ); this->WriteBackSegmentationResult(positionEvent, slice); m_WholeImageContourInWorldCoordinates = NULL; m_SegmentationContourInWorldCoordinates = NULL; return true; }
void WorkbenchUtils::resampleImageItk(itk::Image <PixelType, ImageDimension> *itkImage, Interpolator interpolType, unsigned int *newDimensions, Image::Pointer outImage) { typedef itk::Image <PixelType, ImageDimension> ImageType; // get original image informations const typename ImageType::RegionType &inputRegion = itkImage->GetLargestPossibleRegion(); const typename ImageType::SizeType &inputDimensions = inputRegion.GetSize(); const typename ImageType::SpacingType &inputSpacing = itkImage->GetSpacing(); // calculate spacing double outputSpacing[ImageDimension]; itk::Size <ImageDimension> outputSize; for (unsigned int i = 0; i < ImageDimension; ++i) { outputSpacing[i] = inputSpacing[i] * (double) inputDimensions[i] / newDimensions[i]; outputSize[i] = newDimensions[i]; } // transform typedef itk::IdentityTransform<double, ImageDimension> TransformType; typename TransformType::Pointer transform = TransformType::New(); transform->SetIdentity(); // interpolator typedefs typedef double CoordinateType; typedef itk::LinearInterpolateImageFunction <ImageType, CoordinateType> LinearInterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction <ImageType, CoordinateType> NearestNeighborInterpolatorType; typedef itk::GaussianInterpolateImageFunction <ImageType, CoordinateType> GaussianInterpolatorType; typedef itk::BSplineInterpolateImageFunction <ImageType, CoordinateType> BSplineInterpolatorType; // set up the filter typedef itk::ResampleImageFilter <ImageType, ImageType> ResampleFilterType; typename ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New(); resampleFilter->SetTransform(transform); resampleFilter->SetOutputOrigin(itkImage->GetOrigin()); resampleFilter->SetOutputSpacing(outputSpacing); resampleFilter->SetSize(outputSize); switch (interpolType) { case Interpolator::LINEAR: // the default; resampleFilter->SetInterpolator(LinearInterpolatorType::New()); break; case Interpolator::NEAREST_NEIGHBOR: resampleFilter->SetInterpolator(NearestNeighborInterpolatorType::New()); break; case Interpolator::GAUSSIAN: resampleFilter->SetInterpolator(GaussianInterpolatorType::New()); break; case Interpolator::BSPLINE: resampleFilter->SetInterpolator(BSplineInterpolatorType::New()); break; } resampleFilter->SetInput(itkImage); resampleFilter->UpdateLargestPossibleRegion(); // get the results and cast them back to mitk. return via out parameter. outImage->InitializeByItk(resampleFilter->GetOutput()); CastToMitkImage(resampleFilter->GetOutput(), outImage); }
Image::Pointer WorkbenchUtils::resampleImage(Image::Pointer image, unsigned int *newDimensions, Interpolator interpolationMethod) { // AccessByItk is a precompiler macro that sets up the instantiations for all possible template combinations. This will directly // reflect in the compile time and required memory since functions for all permutations of PixelTypes and Dimensions will be created. // The amount of parameters is not limited. However, a return is not possible. So we work with an out parameter: Image::Pointer returnImage = Image::New(); AccessByItk_n(image.GetPointer(), resampleImageItk, (interpolationMethod, newDimensions, returnImage)); return returnImage; }
void mitk::ImageTimeSelector::GenerateOutputInformation() { Image::ConstPointer input = this->GetInput(); Image::Pointer output = this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); int dim=(input->GetDimension()<3?input->GetDimension():3); output->Initialize(input->GetPixelType(), dim, input->GetDimensions()); if( (unsigned int) m_TimeNr >= input->GetDimension(3) ) { m_TimeNr = input->GetDimension(3)-1; } // initialize geometry output->SetGeometry(dynamic_cast<Geometry3D*>(input->GetSlicedGeometry(m_TimeNr)->Clone().GetPointer())); output->SetPropertyList(input->GetPropertyList()->Clone()); }