mitk::DataNode::Pointer mitk::Tool::CreateEmptySegmentationNode( Image* original, const std::string& organName, const mitk::Color& color ) { // we NEED a reference image for size etc. if (!original) return NULL; // actually create a new empty segmentation PixelType pixelType(mitk::MakeScalarPixelType<DefaultSegmentationDataType>() ); Image::Pointer segmentation = Image::New(); if (original->GetDimension() == 2) { const unsigned int dimensions[] = { original->GetDimension(0), original->GetDimension(1), 1 }; segmentation->Initialize(pixelType, 3, dimensions); } else { segmentation->Initialize(pixelType, original->GetDimension(), original->GetDimensions()); } unsigned int byteSize = sizeof(DefaultSegmentationDataType); if(segmentation->GetDimension() < 4) { for (unsigned int dim = 0; dim < segmentation->GetDimension(); ++dim) { byteSize *= segmentation->GetDimension(dim); } mitk::ImageWriteAccessor writeAccess(segmentation, segmentation->GetVolumeData(0)); memset( writeAccess.GetData(), 0, byteSize ); } else {//if we have a time-resolved image we need to set memory to 0 for each time step for (unsigned int dim = 0; dim < 3; ++dim) { byteSize *= segmentation->GetDimension(dim); } for( unsigned int volumeNumber = 0; volumeNumber < segmentation->GetDimension(3); volumeNumber++) { mitk::ImageWriteAccessor writeAccess(segmentation, segmentation->GetVolumeData(volumeNumber)); memset( writeAccess.GetData(), 0, byteSize ); } } if (original->GetTimeGeometry() ) { TimeGeometry::Pointer originalGeometry = original->GetTimeGeometry()->Clone(); segmentation->SetTimeGeometry( originalGeometry ); } else { Tool::ErrorMessage("Original image does not have a 'Time sliced geometry'! Cannot create a segmentation."); return NULL; } return CreateSegmentationNode( segmentation, organName, color ); }
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(); }
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::CorrectorAlgorithm::GenerateData() { Image::Pointer inputImage = const_cast<Image*>(ImageToImageFilter::GetInput(0)); if (inputImage.IsNull() || inputImage->GetDimension() != 2) { itkExceptionMacro("CorrectorAlgorithm needs a 2D image as input."); } if (m_Contour.IsNull()) { itkExceptionMacro("CorrectorAlgorithm needs a Contour object as input."); } // copy the input (since m_WorkingImage will be changed later) m_WorkingImage = inputImage; TimeGeometry::Pointer originalGeometry = NULL; if (inputImage->GetTimeGeometry() ) { originalGeometry = inputImage->GetTimeGeometry()->Clone(); m_WorkingImage->SetTimeGeometry( originalGeometry ); } else { itkExceptionMacro("Original image does not have a 'Time sliced geometry'! Cannot copy."); } Image::Pointer temporarySlice; // Convert to ipMITKSegmentationTYPE (because TobiasHeimannCorrectionAlgorithm relys on that data type) { itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage; CastToItkImage( m_WorkingImage, correctPixelTypeImage ); assert (correctPixelTypeImage.IsNotNull() ); // possible bug in CastToItkImage ? // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479: // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed // solution here: we overwrite it with an unity matrix itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection; imageDirection.SetIdentity(); //correctPixelTypeImage->SetDirection(imageDirection); temporarySlice = this->GetOutput(); // temporarySlice = ImportItkImage( correctPixelTypeImage ); m_FillColor = 1; m_EraseColor = 0; ImprovedHeimannCorrectionAlgorithm(correctPixelTypeImage); CastToMitkImage( correctPixelTypeImage, temporarySlice ); } temporarySlice->SetTimeGeometry(originalGeometry); }
mitk::DataNode::Pointer mitk::Tool::CreateEmptySegmentationNode( Image* original, const std::string& organName, const mitk::Color& color ) { // we NEED a reference image for size etc. if (!original) return NULL; // actually create a new empty segmentation PixelType pixelType(mitk::MakeScalarPixelType<DefaultSegmentationDataType>() ); Image::Pointer segmentation = Image::New(); if (original->GetDimension() == 2) { const unsigned int dimensions[] = { original->GetDimension(0), original->GetDimension(1), 1 }; segmentation->Initialize(pixelType, 3, dimensions); } else { segmentation->Initialize(pixelType, original->GetDimension(), original->GetDimensions()); } unsigned int byteSize = sizeof(DefaultSegmentationDataType); for (unsigned int dim = 0; dim < segmentation->GetDimension(); ++dim) { byteSize *= segmentation->GetDimension(dim); } memset( segmentation->GetData(), 0, byteSize ); if (original->GetTimeSlicedGeometry() ) { AffineGeometryFrame3D::Pointer originalGeometryAGF = original->GetTimeSlicedGeometry()->Clone(); TimeSlicedGeometry::Pointer originalGeometry = dynamic_cast<TimeSlicedGeometry*>( originalGeometryAGF.GetPointer() ); segmentation->SetGeometry( originalGeometry ); } else { Tool::ErrorMessage("Original image does not have a 'Time sliced geometry'! Cannot create a segmentation."); return NULL; } return CreateSegmentationNode( segmentation, organName, color ); }
static void ReadPixel(const PixelType&, Image::Pointer image, const itk::Index<3>& index, ScalarType* returnValue) { switch (image->GetDimension()) { case 2: { ImagePixelReadAccessor<T, 2> readAccess(image, image->GetSliceData(0)); *returnValue = readAccess.GetPixelByIndex(reinterpret_cast<const itk::Index<2>&>(index)); break; } case 3: { ImagePixelReadAccessor<T, 3> readAccess(image, image->GetVolumeData(0)); *returnValue = readAccess.GetPixelByIndex(index); break; } default: *returnValue = 0; break; } }
bool ShowSegmentationAsSmoothedSurface::ThreadedUpdateFunction() { Image::Pointer image; GetPointerParameter("Input", image); float smoothing; GetParameter("Smoothing", smoothing); float decimation; GetParameter("Decimation", decimation); float closing; GetParameter("Closing", closing); int timeNr = 0; GetParameter("TimeNr", timeNr); if (image->GetDimension() == 4) MITK_INFO << "CREATING SMOOTHED POLYGON MODEL (t = " << timeNr << ')'; else MITK_INFO << "CREATING SMOOTHED POLYGON MODEL"; MITK_INFO << " Smoothing = " << smoothing; MITK_INFO << " Decimation = " << decimation; MITK_INFO << " Closing = " << closing; Geometry3D::Pointer geometry = dynamic_cast<Geometry3D *>(image->GetGeometry()->Clone().GetPointer()); // Make ITK image out of MITK image typedef itk::Image<unsigned char, 3> CharImageType; typedef itk::Image<unsigned short, 3> ShortImageType; typedef itk::Image<float, 3> FloatImageType; if (image->GetDimension() == 4) { ImageTimeSelector::Pointer imageTimeSelector = ImageTimeSelector::New(); imageTimeSelector->SetInput(image); imageTimeSelector->SetTimeNr(timeNr); imageTimeSelector->UpdateLargestPossibleRegion(); image = imageTimeSelector->GetOutput(0); } ImageToItk<CharImageType>::Pointer imageToItkFilter = ImageToItk<CharImageType>::New(); try { imageToItkFilter->SetInput(image); } catch (const itk::ExceptionObject &e) { // Most probably the input image type is wrong. Binary images are expected to be // >unsigned< char images. MITK_ERROR << e.GetDescription() << endl; return false; } imageToItkFilter->Update(); CharImageType::Pointer itkImage = imageToItkFilter->GetOutput(); // Get bounding box and relabel MITK_INFO << "Extracting VOI..."; int imageLabel = 1; bool roiFound = false; CharImageType::IndexType minIndex; minIndex.Fill(numeric_limits<CharImageType::IndexValueType>::max()); CharImageType::IndexType maxIndex; maxIndex.Fill(numeric_limits<CharImageType::IndexValueType>::min()); itk::ImageRegionIteratorWithIndex<CharImageType> iter(itkImage, itkImage->GetLargestPossibleRegion()); for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) { if (iter.Get() == imageLabel) { roiFound = true; iter.Set(1); CharImageType::IndexType currentIndex = iter.GetIndex(); for (unsigned int dim = 0; dim < 3; ++dim) { minIndex[dim] = min(currentIndex[dim], minIndex[dim]); maxIndex[dim] = max(currentIndex[dim], maxIndex[dim]); } } else { iter.Set(0); } } if (!roiFound) { ProgressBar::GetInstance()->Progress(8); MITK_ERROR << "Didn't found segmentation labeled with " << imageLabel << "!" << endl; return false; } ProgressBar::GetInstance()->Progress(1); // Extract and pad bounding box typedef itk::RegionOfInterestImageFilter<CharImageType, CharImageType> ROIFilterType; ROIFilterType::Pointer roiFilter = ROIFilterType::New(); CharImageType::RegionType region; CharImageType::SizeType size; for (unsigned int dim = 0; dim < 3; ++dim) { size[dim] = maxIndex[dim] - minIndex[dim] + 1; } region.SetIndex(minIndex); region.SetSize(size); roiFilter->SetInput(itkImage); roiFilter->SetRegionOfInterest(region); roiFilter->ReleaseDataFlagOn(); roiFilter->ReleaseDataBeforeUpdateFlagOn(); typedef itk::ConstantPadImageFilter<CharImageType, CharImageType> PadFilterType; PadFilterType::Pointer padFilter = PadFilterType::New(); const PadFilterType::SizeValueType pad[3] = { 10, 10, 10 }; padFilter->SetInput(roiFilter->GetOutput()); padFilter->SetConstant(0); padFilter->SetPadLowerBound(pad); padFilter->SetPadUpperBound(pad); padFilter->ReleaseDataFlagOn(); padFilter->ReleaseDataBeforeUpdateFlagOn(); padFilter->Update(); CharImageType::Pointer roiImage = padFilter->GetOutput(); roiImage->DisconnectPipeline(); roiFilter = nullptr; padFilter = nullptr; // Correct origin of real geometry (changed by cropping and padding) typedef Geometry3D::TransformType TransformType; TransformType::Pointer transform = TransformType::New(); TransformType::OutputVectorType translation; for (unsigned int dim = 0; dim < 3; ++dim) translation[dim] = (int)minIndex[dim] - (int)pad[dim]; transform->SetIdentity(); transform->Translate(translation); geometry->Compose(transform, true); ProgressBar::GetInstance()->Progress(1); // Median MITK_INFO << "Median..."; typedef itk::BinaryMedianImageFilter<CharImageType, CharImageType> MedianFilterType; MedianFilterType::Pointer medianFilter = MedianFilterType::New(); CharImageType::SizeType radius = { 0 }; medianFilter->SetRadius(radius); medianFilter->SetBackgroundValue(0); medianFilter->SetForegroundValue(1); medianFilter->SetInput(roiImage); medianFilter->ReleaseDataFlagOn(); medianFilter->ReleaseDataBeforeUpdateFlagOn(); medianFilter->Update(); ProgressBar::GetInstance()->Progress(1); // Intelligent closing MITK_INFO << "Intelligent closing..."; unsigned int surfaceRatio = (unsigned int)((1.0f - closing) * 100.0f); typedef itk::IntelligentBinaryClosingFilter<CharImageType, ShortImageType> ClosingFilterType; ClosingFilterType::Pointer closingFilter = ClosingFilterType::New(); closingFilter->SetInput(medianFilter->GetOutput()); closingFilter->ReleaseDataFlagOn(); closingFilter->ReleaseDataBeforeUpdateFlagOn(); closingFilter->SetSurfaceRatio(surfaceRatio); closingFilter->Update(); ShortImageType::Pointer closedImage = closingFilter->GetOutput(); closedImage->DisconnectPipeline(); roiImage = nullptr; medianFilter = nullptr; closingFilter = nullptr; ProgressBar::GetInstance()->Progress(1); // Gaussian blur MITK_INFO << "Gauss..."; typedef itk::BinaryThresholdImageFilter<ShortImageType, FloatImageType> BinaryThresholdToFloatFilterType; BinaryThresholdToFloatFilterType::Pointer binThresToFloatFilter = BinaryThresholdToFloatFilterType::New(); binThresToFloatFilter->SetInput(closedImage); binThresToFloatFilter->SetLowerThreshold(1); binThresToFloatFilter->SetUpperThreshold(1); binThresToFloatFilter->SetInsideValue(100); binThresToFloatFilter->SetOutsideValue(0); binThresToFloatFilter->ReleaseDataFlagOn(); binThresToFloatFilter->ReleaseDataBeforeUpdateFlagOn(); typedef itk::DiscreteGaussianImageFilter<FloatImageType, FloatImageType> GaussianFilterType; // From the following line on, IntelliSense (VS 2008) is broken. Any idea how to fix it? GaussianFilterType::Pointer gaussFilter = GaussianFilterType::New(); gaussFilter->SetInput(binThresToFloatFilter->GetOutput()); gaussFilter->SetUseImageSpacing(true); gaussFilter->SetVariance(smoothing); gaussFilter->ReleaseDataFlagOn(); gaussFilter->ReleaseDataBeforeUpdateFlagOn(); typedef itk::BinaryThresholdImageFilter<FloatImageType, CharImageType> BinaryThresholdFromFloatFilterType; BinaryThresholdFromFloatFilterType::Pointer binThresFromFloatFilter = BinaryThresholdFromFloatFilterType::New(); binThresFromFloatFilter->SetInput(gaussFilter->GetOutput()); binThresFromFloatFilter->SetLowerThreshold(50); binThresFromFloatFilter->SetUpperThreshold(255); binThresFromFloatFilter->SetInsideValue(1); binThresFromFloatFilter->SetOutsideValue(0); binThresFromFloatFilter->ReleaseDataFlagOn(); binThresFromFloatFilter->ReleaseDataBeforeUpdateFlagOn(); binThresFromFloatFilter->Update(); CharImageType::Pointer blurredImage = binThresFromFloatFilter->GetOutput(); blurredImage->DisconnectPipeline(); closedImage = nullptr; binThresToFloatFilter = nullptr; gaussFilter = nullptr; ProgressBar::GetInstance()->Progress(1); // Fill holes MITK_INFO << "Filling cavities..."; typedef itk::ConnectedThresholdImageFilter<CharImageType, CharImageType> ConnectedThresholdFilterType; ConnectedThresholdFilterType::Pointer connectedThresFilter = ConnectedThresholdFilterType::New(); CharImageType::IndexType corner; corner[0] = 0; corner[1] = 0; corner[2] = 0; connectedThresFilter->SetInput(blurredImage); connectedThresFilter->SetSeed(corner); connectedThresFilter->SetLower(0); connectedThresFilter->SetUpper(0); connectedThresFilter->SetReplaceValue(2); connectedThresFilter->ReleaseDataFlagOn(); connectedThresFilter->ReleaseDataBeforeUpdateFlagOn(); typedef itk::BinaryThresholdImageFilter<CharImageType, CharImageType> BinaryThresholdFilterType; BinaryThresholdFilterType::Pointer binThresFilter = BinaryThresholdFilterType::New(); binThresFilter->SetInput(connectedThresFilter->GetOutput()); binThresFilter->SetLowerThreshold(0); binThresFilter->SetUpperThreshold(0); binThresFilter->SetInsideValue(50); binThresFilter->SetOutsideValue(0); binThresFilter->ReleaseDataFlagOn(); binThresFilter->ReleaseDataBeforeUpdateFlagOn(); typedef itk::AddImageFilter<CharImageType, CharImageType, CharImageType> AddFilterType; AddFilterType::Pointer addFilter = AddFilterType::New(); addFilter->SetInput1(blurredImage); addFilter->SetInput2(binThresFilter->GetOutput()); addFilter->ReleaseDataFlagOn(); addFilter->ReleaseDataBeforeUpdateFlagOn(); addFilter->Update(); ProgressBar::GetInstance()->Progress(1); // Surface extraction MITK_INFO << "Surface extraction..."; Image::Pointer filteredImage = Image::New(); CastToMitkImage(addFilter->GetOutput(), filteredImage); filteredImage->SetGeometry(geometry); ImageToSurfaceFilter::Pointer imageToSurfaceFilter = ImageToSurfaceFilter::New(); imageToSurfaceFilter->SetInput(filteredImage); imageToSurfaceFilter->SetThreshold(50); imageToSurfaceFilter->SmoothOn(); imageToSurfaceFilter->SetDecimate(ImageToSurfaceFilter::NoDecimation); m_Surface = imageToSurfaceFilter->GetOutput(0); ProgressBar::GetInstance()->Progress(1); // Mesh decimation if (decimation > 0.0f && decimation < 1.0f) { MITK_INFO << "Quadric mesh decimation..."; vtkQuadricDecimation *quadricDecimation = vtkQuadricDecimation::New(); quadricDecimation->SetInputData(m_Surface->GetVtkPolyData()); quadricDecimation->SetTargetReduction(decimation); quadricDecimation->AttributeErrorMetricOn(); quadricDecimation->GlobalWarningDisplayOff(); quadricDecimation->Update(); vtkCleanPolyData* cleaner = vtkCleanPolyData::New(); cleaner->SetInputConnection(quadricDecimation->GetOutputPort()); cleaner->PieceInvariantOn(); cleaner->ConvertLinesToPointsOn(); cleaner->ConvertStripsToPolysOn(); cleaner->PointMergingOn(); cleaner->Update(); m_Surface->SetVtkPolyData(cleaner->GetOutput()); } ProgressBar::GetInstance()->Progress(1); // Compute Normals vtkPolyDataNormals* computeNormals = vtkPolyDataNormals::New(); computeNormals->SetInputData(m_Surface->GetVtkPolyData()); computeNormals->SetFeatureAngle(360.0f); computeNormals->FlipNormalsOff(); computeNormals->Update(); m_Surface->SetVtkPolyData(computeNormals->GetOutput()); return true; }
std::vector<BaseData::Pointer> ItkImageIO::Read() { std::vector<BaseData::Pointer> result; mitk::LocaleSwitch localeSwitch("C"); Image::Pointer image = Image::New(); const unsigned int MINDIM = 2; const unsigned int MAXDIM = 4; const std::string path = this->GetLocalFileName(); MITK_INFO << "loading " << path << " via itk::ImageIOFactory... " << std::endl; // Check to see if we can read the file given the name or prefix if (path.empty()) { mitkThrow() << "Empty filename in mitk::ItkImageIO "; } // Got to allocate space for the image. Determine the characteristics of // the image. m_ImageIO->SetFileName(path); m_ImageIO->ReadImageInformation(); unsigned int ndim = m_ImageIO->GetNumberOfDimensions(); if (ndim < MINDIM || ndim > MAXDIM) { MITK_WARN << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim << " dimensions! Reading as 4D."; ndim = MAXDIM; } itk::ImageIORegion ioRegion(ndim); itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize(); itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex(); unsigned int dimensions[MAXDIM]; dimensions[0] = 0; dimensions[1] = 0; dimensions[2] = 0; dimensions[3] = 0; ScalarType spacing[MAXDIM]; spacing[0] = 1.0f; spacing[1] = 1.0f; spacing[2] = 1.0f; spacing[3] = 1.0f; Point3D origin; origin.Fill(0); unsigned int i; for (i = 0; i < ndim; ++i) { ioStart[i] = 0; ioSize[i] = m_ImageIO->GetDimensions(i); if (i < MAXDIM) { dimensions[i] = m_ImageIO->GetDimensions(i); spacing[i] = m_ImageIO->GetSpacing(i); if (spacing[i] <= 0) spacing[i] = 1.0f; } if (i < 3) { origin[i] = m_ImageIO->GetOrigin(i); } } ioRegion.SetSize(ioSize); ioRegion.SetIndex(ioStart); MITK_INFO << "ioRegion: " << ioRegion << std::endl; m_ImageIO->SetIORegion(ioRegion); void *buffer = new unsigned char[m_ImageIO->GetImageSizeInBytes()]; m_ImageIO->Read(buffer); image->Initialize(MakePixelType(m_ImageIO), ndim, dimensions); image->SetImportChannel(buffer, 0, Image::ManageMemory); const itk::MetaDataDictionary &dictionary = m_ImageIO->GetMetaDataDictionary(); // access direction of itk::Image and include spacing mitk::Matrix3D matrix; matrix.SetIdentity(); unsigned int j, itkDimMax3 = (ndim >= 3 ? 3 : ndim); for (i = 0; i < itkDimMax3; ++i) for (j = 0; j < itkDimMax3; ++j) matrix[i][j] = m_ImageIO->GetDirection(j)[i]; // re-initialize PlaneGeometry with origin and direction PlaneGeometry *planeGeometry = image->GetSlicedGeometry(0)->GetPlaneGeometry(0); planeGeometry->SetOrigin(origin); planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix); // re-initialize SlicedGeometry3D SlicedGeometry3D *slicedGeometry = image->GetSlicedGeometry(0); slicedGeometry->InitializeEvenlySpaced(planeGeometry, image->GetDimension(2)); slicedGeometry->SetSpacing(spacing); MITK_INFO << slicedGeometry->GetCornerPoint(false, false, false); MITK_INFO << slicedGeometry->GetCornerPoint(true, true, true); // re-initialize TimeGeometry TimeGeometry::Pointer timeGeometry; if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TYPE) || dictionary.HasKey(PROPERTY_KEY_TIMEGEOMETRY_TYPE)) { // also check for the name because of backwards compatibility. Past code version stored with the name and not with // the key itk::MetaDataObject<std::string>::ConstPointer timeGeometryTypeData = nullptr; if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TYPE)) { timeGeometryTypeData = dynamic_cast<const itk::MetaDataObject<std::string> *>(dictionary.Get(PROPERTY_NAME_TIMEGEOMETRY_TYPE)); } else { timeGeometryTypeData = dynamic_cast<const itk::MetaDataObject<std::string> *>(dictionary.Get(PROPERTY_KEY_TIMEGEOMETRY_TYPE)); } if (timeGeometryTypeData->GetMetaDataObjectValue() == ArbitraryTimeGeometry::GetStaticNameOfClass()) { MITK_INFO << "used time geometry: " << ArbitraryTimeGeometry::GetStaticNameOfClass() << std::endl; typedef std::vector<TimePointType> TimePointVector; TimePointVector timePoints; if (dictionary.HasKey(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS)) { timePoints = ConvertMetaDataObjectToTimePointList(dictionary.Get(PROPERTY_NAME_TIMEGEOMETRY_TIMEPOINTS)); } else if (dictionary.HasKey(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS)) { timePoints = ConvertMetaDataObjectToTimePointList(dictionary.Get(PROPERTY_KEY_TIMEGEOMETRY_TIMEPOINTS)); } if (timePoints.size() - 1 != image->GetDimension(3)) { MITK_ERROR << "Stored timepoints (" << timePoints.size() - 1 << ") and size of image time dimension (" << image->GetDimension(3) << ") do not match. Switch to ProportionalTimeGeometry fallback" << std::endl; } else { ArbitraryTimeGeometry::Pointer arbitraryTimeGeometry = ArbitraryTimeGeometry::New(); TimePointVector::const_iterator pos = timePoints.begin(); TimePointVector::const_iterator prePos = pos++; for (; pos != timePoints.end(); ++prePos, ++pos) { arbitraryTimeGeometry->AppendTimeStepClone(slicedGeometry, *pos, *prePos); } timeGeometry = arbitraryTimeGeometry; } } } if (timeGeometry.IsNull()) { // Fallback. If no other valid time geometry has been created, create a ProportionalTimeGeometry MITK_INFO << "used time geometry: " << ProportionalTimeGeometry::GetStaticNameOfClass() << std::endl; ProportionalTimeGeometry::Pointer propTimeGeometry = ProportionalTimeGeometry::New(); propTimeGeometry->Initialize(slicedGeometry, image->GetDimension(3)); timeGeometry = propTimeGeometry; } image->SetTimeGeometry(timeGeometry); buffer = NULL; MITK_INFO << "number of image components: " << image->GetPixelType().GetNumberOfComponents() << std::endl; for (itk::MetaDataDictionary::ConstIterator iter = dictionary.Begin(), iterEnd = dictionary.End(); iter != iterEnd; ++iter) { if (iter->second->GetMetaDataObjectTypeInfo() == typeid(std::string)) { const std::string &key = iter->first; std::string assumedPropertyName = key; std::replace(assumedPropertyName.begin(), assumedPropertyName.end(), '_', '.'); std::string mimeTypeName = GetMimeType()->GetName(); // Check if there is already a info for the key and our mime type. IPropertyPersistence::InfoResultType infoList = mitk::CoreServices::GetPropertyPersistence()->GetInfoByKey(key); auto predicate = [mimeTypeName](const PropertyPersistenceInfo::ConstPointer &x) { return x.IsNotNull() && x->GetMimeTypeName() == mimeTypeName; }; auto finding = std::find_if(infoList.begin(), infoList.end(), predicate); if (finding == infoList.end()) { auto predicateWild = [](const PropertyPersistenceInfo::ConstPointer &x) { return x.IsNotNull() && x->GetMimeTypeName() == PropertyPersistenceInfo::ANY_MIMETYPE_NAME(); }; finding = std::find_if(infoList.begin(), infoList.end(), predicateWild); } PropertyPersistenceInfo::ConstPointer info; if (finding != infoList.end()) { assumedPropertyName = (*finding)->GetName(); info = *finding; } else { // we have not found anything suitable so we generate our own info PropertyPersistenceInfo::Pointer newInfo = PropertyPersistenceInfo::New(); newInfo->SetNameAndKey(assumedPropertyName, key); newInfo->SetMimeTypeName(PropertyPersistenceInfo::ANY_MIMETYPE_NAME()); info = newInfo; } std::string value = dynamic_cast<itk::MetaDataObject<std::string> *>(iter->second.GetPointer())->GetMetaDataObjectValue(); mitk::BaseProperty::Pointer loadedProp = info->GetDeserializationFunction()(value); image->SetProperty(assumedPropertyName.c_str(), loadedProp); // Read properties should be persisted unless they are default properties // which are written anyway bool isDefaultKey(false); for (const auto &defaultKey : m_DefaultMetaDataKeys) { if (defaultKey.length() <= assumedPropertyName.length()) { // does the start match the default key if (assumedPropertyName.substr(0, defaultKey.length()).find(defaultKey) != std::string::npos) { isDefaultKey = true; break; } } } if (!isDefaultKey) { mitk::CoreServices::GetPropertyPersistence()->AddInfo(info); } } } MITK_INFO << "...finished!" << std::endl; result.push_back(image.GetPointer()); return result; }
bool ShowSegmentationAsSurface::ThreadedUpdateFunction() { Image::Pointer image; GetPointerParameter("Input", image); bool smooth(true); GetParameter("Smooth", smooth); bool applyMedian(true); GetParameter("Apply median", applyMedian); bool decimateMesh(true); GetParameter("Decimate mesh", decimateMesh); unsigned int medianKernelSize(3); GetParameter("Median kernel size", medianKernelSize); float gaussianSD(1.5); GetParameter("Gaussian SD", gaussianSD); float reductionRate(0.8); GetParameter("Decimation rate", reductionRate); MITK_INFO << "Creating polygon model with smoothing " << smooth << " gaussianSD " << gaussianSD << " median " << applyMedian << " median kernel " << medianKernelSize << " mesh reduction " << decimateMesh << " reductionRate " << reductionRate; ManualSegmentationToSurfaceFilter::Pointer surfaceFilter = ManualSegmentationToSurfaceFilter::New(); surfaceFilter->SetInput(image); surfaceFilter->SetThreshold(0.5); // expects binary image with zeros and ones surfaceFilter->SetUseGaussianImageSmooth(smooth); // apply gaussian to thresholded image ? surfaceFilter->SetSmooth(smooth); if (smooth) { surfaceFilter->InterpolationOn(); surfaceFilter->SetGaussianStandardDeviation(gaussianSD); } surfaceFilter->SetMedianFilter3D(applyMedian); // apply median to segmentation before marching cubes ? if (applyMedian) { surfaceFilter->SetMedianKernelSize( medianKernelSize, medianKernelSize, medianKernelSize); // apply median to segmentation before marching cubes } // fix to avoid vtk warnings see bug #5390 if (image->GetDimension() > 3) decimateMesh = false; if (decimateMesh) { surfaceFilter->SetDecimate(ImageToSurfaceFilter::QuadricDecimation); surfaceFilter->SetTargetReduction(reductionRate); } else { surfaceFilter->SetDecimate(ImageToSurfaceFilter::NoDecimation); } surfaceFilter->UpdateLargestPossibleRegion(); // calculate normals for nicer display m_Surface = surfaceFilter->GetOutput(); vtkPolyData *polyData = m_Surface->GetVtkPolyData(); if (!polyData) throw std::logic_error("Could not create polygon model"); polyData->SetVerts(0); polyData->SetLines(0); if (smooth || applyMedian || decimateMesh) { vtkPolyDataNormals *normalsGen = vtkPolyDataNormals::New(); normalsGen->AutoOrientNormalsOn(); normalsGen->FlipNormalsOff(); normalsGen->SetInputData(polyData); normalsGen->Update(); m_Surface->SetVtkPolyData(normalsGen->GetOutput()); normalsGen->Delete(); } else { m_Surface->SetVtkPolyData(polyData); } return true; }
void mitk::PicFileReader::GenerateData() { Image::Pointer output = this->GetOutput(); // Check to see if we can read the file given the name or prefix // if ( m_FileName == "" && m_FilePrefix == "" ) { throw itk::ImageFileReaderException(__FILE__, __LINE__, "One of FileName or FilePrefix must be non-empty"); } if( m_FileName != "") { mitkIpPicDescriptor* outputPic = mitkIpPicNew(); outputPic = CastToIpPicDescriptor(output, outputPic); mitkIpPicDescriptor* pic=MITKipPicGet(const_cast<char *>(m_FileName.c_str()), outputPic); // comes upside-down (in MITK coordinates) from PIC file ConvertHandedness(pic); mitkIpPicTSV_t *tsv; if ( (tsv = mitkIpPicQueryTag( pic, "SOURCE HEADER" )) != NULL) { if(tsv->n[0]>1e+06) { mitkIpPicTSV_t *tsvSH; tsvSH = mitkIpPicDelTag( pic, "SOURCE HEADER" ); mitkIpPicFreeTag(tsvSH); } } if ( (tsv = mitkIpPicQueryTag( pic, "ICON80x80" )) != NULL) { mitkIpPicTSV_t *tsvSH; tsvSH = mitkIpPicDelTag( pic, "ICON80x80" ); mitkIpPicFreeTag(tsvSH); } if ( (tsv = mitkIpPicQueryTag( pic, "VELOCITY" )) != NULL) { mitkIpPicDescriptor* header = mitkIpPicCopyHeader(pic, NULL); header->data = tsv->value; ConvertHandedness(header); output->SetChannel(header->data, 1); header->data = NULL; mitkIpPicFree(header); mitkIpPicDelTag( pic, "VELOCITY" ); } //slice-wise reading //currently much too slow. //else //{ // int sstart, smax; // int tstart, tmax; // sstart=output->GetRequestedRegion().GetIndex(2); // smax=sstart+output->GetRequestedRegion().GetSize(2); // tstart=output->GetRequestedRegion().GetIndex(3); // tmax=tstart+output->GetRequestedRegion().GetSize(3); // int s,t; // for(s=sstart; s<smax; ++s) // { // for(t=tstart; t<tmax; ++t) // { // mitkIpPicDescriptor* pic=mitkIpPicGetSlice(const_cast<char *>(m_FileName.c_str()), NULL, t*smax+s+1); // output->SetPicSlice(pic,s,t); // } // } //} } else { int position; mitkIpPicDescriptor* pic=NULL; int zDim=(output->GetDimension()>2?output->GetDimensions()[2]:1); printf("\n zdim is %u \n",zDim); for (position = 0; position < zDim; ++position) { char fullName[1024]; sprintf(fullName, m_FilePattern.c_str(), m_FilePrefix.c_str(), m_StartFileIndex+position); pic=MITKipPicGet(fullName, pic); if(pic==NULL) { itkDebugMacro("Pic file '" << fullName << "' does not exist."); } /* FIXME else if(output->SetPicSlice(pic, position)==false) { itkDebugMacro("Image '" << fullName << "' could not be added to Image."); }*/ } if(pic!=NULL) mitkIpPicFree(pic); } }
std::vector<BaseData::Pointer> LabelSetImageIO::Read() { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { mitkThrow() << "Could not set locale."; } } // begin regular image loading, adapted from mitkItkImageIO itk::NrrdImageIO::Pointer nrrdImageIO = itk::NrrdImageIO::New(); Image::Pointer image = Image::New(); const unsigned int MINDIM = 2; const unsigned int MAXDIM = 4; const std::string path = this->GetLocalFileName(); MITK_INFO << "loading " << path << " via itk::ImageIOFactory... " << std::endl; // Check to see if we can read the file given the name or prefix if (path.empty()) { mitkThrow() << "Empty filename in mitk::ItkImageIO "; } // Got to allocate space for the image. Determine the characteristics of // the image. nrrdImageIO->SetFileName(path); nrrdImageIO->ReadImageInformation(); unsigned int ndim = nrrdImageIO->GetNumberOfDimensions(); if (ndim < MINDIM || ndim > MAXDIM) { MITK_WARN << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim << " dimensions! Reading as 4D."; ndim = MAXDIM; } itk::ImageIORegion ioRegion(ndim); itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize(); itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex(); unsigned int dimensions[MAXDIM]; dimensions[0] = 0; dimensions[1] = 0; dimensions[2] = 0; dimensions[3] = 0; ScalarType spacing[MAXDIM]; spacing[0] = 1.0f; spacing[1] = 1.0f; spacing[2] = 1.0f; spacing[3] = 1.0f; Point3D origin; origin.Fill(0); unsigned int i; for (i = 0; i < ndim; ++i) { ioStart[i] = 0; ioSize[i] = nrrdImageIO->GetDimensions(i); if (i<MAXDIM) { dimensions[i] = nrrdImageIO->GetDimensions(i); spacing[i] = nrrdImageIO->GetSpacing(i); if (spacing[i] <= 0) spacing[i] = 1.0f; } if (i<3) { origin[i] = nrrdImageIO->GetOrigin(i); } } ioRegion.SetSize(ioSize); ioRegion.SetIndex(ioStart); MITK_INFO << "ioRegion: " << ioRegion << std::endl; nrrdImageIO->SetIORegion(ioRegion); void* buffer = new unsigned char[nrrdImageIO->GetImageSizeInBytes()]; nrrdImageIO->Read(buffer); image->Initialize(MakePixelType(nrrdImageIO), ndim, dimensions); image->SetImportChannel(buffer, 0, Image::ManageMemory); // access direction of itk::Image and include spacing mitk::Matrix3D matrix; matrix.SetIdentity(); unsigned int j, itkDimMax3 = (ndim >= 3 ? 3 : ndim); for (i = 0; i < itkDimMax3; ++i) for (j = 0; j < itkDimMax3; ++j) matrix[i][j] = nrrdImageIO->GetDirection(j)[i]; // re-initialize PlaneGeometry with origin and direction PlaneGeometry* planeGeometry = image->GetSlicedGeometry(0)->GetPlaneGeometry(0); planeGeometry->SetOrigin(origin); planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix); // re-initialize SlicedGeometry3D SlicedGeometry3D* slicedGeometry = image->GetSlicedGeometry(0); slicedGeometry->InitializeEvenlySpaced(planeGeometry, image->GetDimension(2)); slicedGeometry->SetSpacing(spacing); MITK_INFO << slicedGeometry->GetCornerPoint(false, false, false); MITK_INFO << slicedGeometry->GetCornerPoint(true, true, true); // re-initialize TimeGeometry ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, image->GetDimension(3)); image->SetTimeGeometry(timeGeometry); buffer = NULL; MITK_INFO << "number of image components: " << image->GetPixelType().GetNumberOfComponents() << std::endl; const itk::MetaDataDictionary& dictionary = nrrdImageIO->GetMetaDataDictionary(); for (itk::MetaDataDictionary::ConstIterator iter = dictionary.Begin(), iterEnd = dictionary.End(); iter != iterEnd; ++iter) { std::string key = std::string("meta.") + iter->first; if (iter->second->GetMetaDataObjectTypeInfo() == typeid(std::string)) { std::string value = dynamic_cast<itk::MetaDataObject<std::string>*>(iter->second.GetPointer())->GetMetaDataObjectValue(); image->SetProperty(key.c_str(), mitk::StringProperty::New(value)); } } // end regular image loading LabelSetImage::Pointer output = LabelSetImageConverter::ConvertImageToLabelSetImage(image); // get labels and add them as properties to the image char keybuffer[256]; unsigned int numberOfLayers = GetIntByKey(dictionary, "layers"); std::string _xmlStr; mitk::Label::Pointer label; for (unsigned int layerIdx = 0; layerIdx < numberOfLayers; layerIdx++) { sprintf(keybuffer, "layer_%03d", layerIdx); int numberOfLabels = GetIntByKey(dictionary, keybuffer); mitk::LabelSet::Pointer labelSet = mitk::LabelSet::New(); for (int labelIdx = 0; labelIdx < numberOfLabels; labelIdx++) { TiXmlDocument doc; sprintf(keybuffer, "label_%03d_%05d", layerIdx, labelIdx); _xmlStr = GetStringByKey(dictionary, keybuffer); doc.Parse(_xmlStr.c_str()); TiXmlElement * labelElem = doc.FirstChildElement("Label"); if (labelElem == 0) mitkThrow() << "Error parsing NRRD header for mitk::LabelSetImage IO"; label = LoadLabelFromTiXmlDocument(labelElem); if (label->GetValue() == 0) // set exterior label is needed to hold exterior information output->SetExteriorLabel(label); labelSet->AddLabel(label); labelSet->SetLayer(layerIdx); } output->AddLabelSetToLayer(layerIdx, labelSet); } MITK_INFO << "...finished!" << std::endl; try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { mitkThrow() << "Could not reset locale!"; } std::vector<BaseData::Pointer> result; result.push_back(output.GetPointer()); return result; }
void mitk::CorrectorAlgorithm::GenerateData() { Image::Pointer inputImage = const_cast<Image*>(ImageToImageFilter::GetInput(0)); if (inputImage.IsNull() || inputImage->GetDimension() != 2) { itkExceptionMacro("CorrectorAlgorithm needs a 2D image as input."); } if (m_Contour.IsNull()) { itkExceptionMacro("CorrectorAlgorithm needs a Contour object as input."); } // copy the input (since m_WorkingImage will be changed later) m_WorkingImage = Image::New(); m_WorkingImage->Initialize( inputImage ); m_WorkingImage->SetVolume( inputImage.GetPointer()->GetData() ); if (inputImage->GetTimeSlicedGeometry() ) { AffineGeometryFrame3D::Pointer originalGeometryAGF = inputImage->GetTimeSlicedGeometry()->Clone(); TimeSlicedGeometry::Pointer originalGeometry = dynamic_cast<TimeSlicedGeometry*>( originalGeometryAGF.GetPointer() ); m_WorkingImage->SetGeometry( originalGeometry ); } else { itkExceptionMacro("Original image does not have a 'Time sliced geometry'! Cannot copy."); } // Convert to ipMITKSegmentationTYPE (because TobiasHeimannCorrectionAlgorithm relys on that data type) itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage; CastToItkImage( m_WorkingImage, correctPixelTypeImage ); assert (correctPixelTypeImage.IsNotNull() ); // possible bug in CastToItkImage ? // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479: // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed // solution here: we overwrite it with an unity matrix itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection; imageDirection.SetIdentity(); correctPixelTypeImage->SetDirection(imageDirection); Image::Pointer temporarySlice = this->GetOutput(); // temporarySlice = ImportItkImage( correctPixelTypeImage ); CastToMitkImage( correctPixelTypeImage, temporarySlice ); TobiasHeimannCorrectionAlgorithm( temporarySlice->GetSliceData()->GetPicDescriptor() ); // temporarySlice is our return value (user can get it by calling GetOutput() ) CalculateDifferenceImage( temporarySlice, inputImage ); if ( m_DifferenceImage.IsNotNull() && inputImage->GetTimeSlicedGeometry() ) { AffineGeometryFrame3D::Pointer originalGeometryAGF = inputImage->GetTimeSlicedGeometry()->Clone(); TimeSlicedGeometry::Pointer originalGeometry = dynamic_cast<TimeSlicedGeometry*>( originalGeometryAGF.GetPointer() ); m_DifferenceImage->SetGeometry( originalGeometry ); } else { itkExceptionMacro("Original image does not have a 'Time sliced geometry'! Cannot copy."); } }
mitk::GIFVolumetricStatistics::FeatureListType mitk::GIFVolumetricStatistics::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { FeatureListType featureList; if (image->GetDimension() < 3) { return featureList; } AccessByItk_3(image, CalculateVolumeStatistic, mask, featureList, FeatureDescriptionPrefix()); AccessByItk_3(mask, CalculateLargestDiameter, image, featureList, FeatureDescriptionPrefix()); vtkSmartPointer<vtkImageMarchingCubes> mesher = vtkSmartPointer<vtkImageMarchingCubes>::New(); vtkSmartPointer<vtkMassProperties> stats = vtkSmartPointer<vtkMassProperties>::New(); mesher->SetInputData(mask->GetVtkImageData()); mesher->SetValue(0, 0.5); stats->SetInputConnection(mesher->GetOutputPort()); stats->Update(); double pi = vnl_math::pi; double meshVolume = stats->GetVolume(); double meshSurf = stats->GetSurfaceArea(); double pixelVolume = featureList[1].second; double pixelSurface = featureList[3].second; MITK_INFO << "Surface: " << pixelSurface << " Volume: " << pixelVolume; double compactness1 = pixelVolume / (std::sqrt(pi) * std::pow(meshSurf, 2.0 / 3.0)); double compactness1Pixel = pixelVolume / (std::sqrt(pi) * std::pow(pixelSurface, 2.0 / 3.0)); //This is the definition used by Aertz. However, due to 2/3 this feature is not demensionless. Use compactness3 instead. double compactness2 = 36 * pi*pixelVolume*pixelVolume / meshSurf / meshSurf / meshSurf; double compactness2MeshMesh = 36 * pi*meshVolume*meshVolume / meshSurf / meshSurf / meshSurf; double compactness2Pixel = 36 * pi*pixelVolume*pixelVolume / pixelSurface / pixelSurface / pixelSurface; double compactness3 = pixelVolume / (std::sqrt(pi) * std::pow(meshSurf, 3.0 / 2.0)); double compactness3MeshMesh = meshVolume / (std::sqrt(pi) * std::pow(meshSurf, 3.0 / 2.0)); double compactness3Pixel = pixelVolume / (std::sqrt(pi) * std::pow(pixelSurface, 3.0 / 2.0)); double sphericity = std::pow(pi, 1 / 3.0) *std::pow(6 * pixelVolume, 2.0 / 3.0) / meshSurf; double sphericityMesh = std::pow(pi, 1 / 3.0) *std::pow(6 * meshVolume, 2.0 / 3.0) / meshSurf; double sphericityPixel = std::pow(pi, 1 / 3.0) *std::pow(6 * pixelVolume, 2.0 / 3.0) / pixelSurface; double surfaceToVolume = meshSurf / meshVolume; double surfaceToVolumePixel = pixelSurface / pixelVolume; double sphericalDisproportion = meshSurf / 4 / pi / std::pow(3.0 / 4.0 / pi * pixelVolume, 2.0 / 3.0); double sphericalDisproportionMesh = meshSurf / 4 / pi / std::pow(3.0 / 4.0 / pi * meshVolume, 2.0 / 3.0); double sphericalDisproportionPixel = pixelSurface / 4 / pi / std::pow(3.0 / 4.0 / pi * pixelVolume, 2.0 / 3.0); double asphericity = std::pow(1.0/compactness2, (1.0 / 3.0)) - 1; double asphericityMesh = std::pow(1.0 / compactness2MeshMesh, (1.0 / 3.0)) - 1; double asphericityPixel = std::pow(1.0/compactness2Pixel, (1.0 / 3.0)) - 1; //Calculate center of mass shift int xx = mask->GetDimensions()[0]; int yy = mask->GetDimensions()[1]; int zz = mask->GetDimensions()[2]; double xd = mask->GetGeometry()->GetSpacing()[0]; double yd = mask->GetGeometry()->GetSpacing()[1]; double zd = mask->GetGeometry()->GetSpacing()[2]; vtkSmartPointer<vtkDoubleArray> dataset1Arr = vtkSmartPointer<vtkDoubleArray>::New(); vtkSmartPointer<vtkDoubleArray> dataset2Arr = vtkSmartPointer<vtkDoubleArray>::New(); vtkSmartPointer<vtkDoubleArray> dataset3Arr = vtkSmartPointer<vtkDoubleArray>::New(); dataset1Arr->SetNumberOfComponents(1); dataset2Arr->SetNumberOfComponents(1); dataset3Arr->SetNumberOfComponents(1); dataset1Arr->SetName("M1"); dataset2Arr->SetName("M2"); dataset3Arr->SetName("M3"); vtkSmartPointer<vtkDoubleArray> dataset1ArrU = vtkSmartPointer<vtkDoubleArray>::New(); vtkSmartPointer<vtkDoubleArray> dataset2ArrU = vtkSmartPointer<vtkDoubleArray>::New(); vtkSmartPointer<vtkDoubleArray> dataset3ArrU = vtkSmartPointer<vtkDoubleArray>::New(); dataset1ArrU->SetNumberOfComponents(1); dataset2ArrU->SetNumberOfComponents(1); dataset3ArrU->SetNumberOfComponents(1); dataset1ArrU->SetName("M1"); dataset2ArrU->SetName("M2"); dataset3ArrU->SetName("M3"); for (int x = 0; x < xx; x++) { for (int y = 0; y < yy; y++) { for (int z = 0; z < zz; z++) { itk::Image<int,3>::IndexType index; index[0] = x; index[1] = y; index[2] = z; mitk::ScalarType pxImage; mitk::ScalarType pxMask; mitkPixelTypeMultiplex5( mitk::FastSinglePixelAccess, image->GetChannelDescriptor().GetPixelType(), image, image->GetVolumeData(), index, pxImage, 0); mitkPixelTypeMultiplex5( mitk::FastSinglePixelAccess, mask->GetChannelDescriptor().GetPixelType(), mask, mask->GetVolumeData(), index, pxMask, 0); //Check if voxel is contained in segmentation if (pxMask > 0) { dataset1ArrU->InsertNextValue(x*xd); dataset2ArrU->InsertNextValue(y*yd); dataset3ArrU->InsertNextValue(z*zd); if (pxImage == pxImage) { dataset1Arr->InsertNextValue(x*xd); dataset2Arr->InsertNextValue(y*yd); dataset3Arr->InsertNextValue(z*zd); } } } } } vtkSmartPointer<vtkTable> datasetTable = vtkSmartPointer<vtkTable>::New(); datasetTable->AddColumn(dataset1Arr); datasetTable->AddColumn(dataset2Arr); datasetTable->AddColumn(dataset3Arr); vtkSmartPointer<vtkTable> datasetTableU = vtkSmartPointer<vtkTable>::New(); datasetTableU->AddColumn(dataset1ArrU); datasetTableU->AddColumn(dataset2ArrU); datasetTableU->AddColumn(dataset3ArrU); vtkSmartPointer<vtkPCAStatistics> pcaStatistics = vtkSmartPointer<vtkPCAStatistics>::New(); pcaStatistics->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, datasetTable); pcaStatistics->SetColumnStatus("M1", 1); pcaStatistics->SetColumnStatus("M2", 1); pcaStatistics->SetColumnStatus("M3", 1); pcaStatistics->RequestSelectedColumns(); pcaStatistics->SetDeriveOption(true); pcaStatistics->Update(); vtkSmartPointer<vtkDoubleArray> eigenvalues = vtkSmartPointer<vtkDoubleArray>::New(); pcaStatistics->GetEigenvalues(eigenvalues); pcaStatistics->SetInputData(vtkStatisticsAlgorithm::INPUT_DATA, datasetTableU); pcaStatistics->Update(); vtkSmartPointer<vtkDoubleArray> eigenvaluesU = vtkSmartPointer<vtkDoubleArray>::New(); pcaStatistics->GetEigenvalues(eigenvaluesU); std::vector<double> eigen_val(3); std::vector<double> eigen_valUC(3); eigen_val[2] = eigenvalues->GetValue(0); eigen_val[1] = eigenvalues->GetValue(1); eigen_val[0] = eigenvalues->GetValue(2); eigen_valUC[2] = eigenvaluesU->GetValue(0); eigen_valUC[1] = eigenvaluesU->GetValue(1); eigen_valUC[0] = eigenvaluesU->GetValue(2); double major = 4*sqrt(eigen_val[2]); double minor = 4*sqrt(eigen_val[1]); double least = 4*sqrt(eigen_val[0]); double elongation = (major == 0) ? 0 : sqrt(eigen_val[1] / eigen_val[2]); double flatness = (major == 0) ? 0 : sqrt(eigen_val[0] / eigen_val[2]); double majorUC = 4*sqrt(eigen_valUC[2]); double minorUC = 4*sqrt(eigen_valUC[1]); double leastUC = 4*sqrt(eigen_valUC[0]); double elongationUC = majorUC == 0 ? 0 : sqrt(eigen_valUC[1] / eigen_valUC[2]); double flatnessUC = majorUC == 0 ? 0 : sqrt(eigen_valUC[0] / eigen_valUC[2]); std::string prefix = FeatureDescriptionPrefix(); featureList.push_back(std::make_pair(prefix + "Volume (mesh based)",meshVolume)); featureList.push_back(std::make_pair(prefix + "Surface (mesh based)",meshSurf)); featureList.push_back(std::make_pair(prefix + "Surface to volume ratio (mesh based)",surfaceToVolume)); featureList.push_back(std::make_pair(prefix + "Sphericity (mesh based)",sphericity)); featureList.push_back(std::make_pair(prefix + "Sphericity (mesh, mesh based)", sphericityMesh)); featureList.push_back(std::make_pair(prefix + "Asphericity (mesh based)", asphericity)); featureList.push_back(std::make_pair(prefix + "Asphericity (mesh, mesh based)", asphericityMesh)); featureList.push_back(std::make_pair(prefix + "Compactness 1 (mesh based)", compactness3)); featureList.push_back(std::make_pair(prefix + "Compactness 1 old (mesh based)" ,compactness1)); featureList.push_back(std::make_pair(prefix + "Compactness 2 (mesh based)",compactness2)); featureList.push_back(std::make_pair(prefix + "Compactness 1 (mesh, mesh based)", compactness3MeshMesh)); featureList.push_back(std::make_pair(prefix + "Compactness 2 (mesh, mesh based)", compactness2MeshMesh)); featureList.push_back(std::make_pair(prefix + "Spherical disproportion (mesh based)", sphericalDisproportion)); featureList.push_back(std::make_pair(prefix + "Spherical disproportion (mesh, mesh based)", sphericalDisproportionMesh)); featureList.push_back(std::make_pair(prefix + "Surface to volume ratio (voxel based)", surfaceToVolumePixel)); featureList.push_back(std::make_pair(prefix + "Sphericity (voxel based)", sphericityPixel)); featureList.push_back(std::make_pair(prefix + "Asphericity (voxel based)", asphericityPixel)); featureList.push_back(std::make_pair(prefix + "Compactness 1 (voxel based)", compactness3Pixel)); featureList.push_back(std::make_pair(prefix + "Compactness 1 old (voxel based)", compactness1Pixel)); featureList.push_back(std::make_pair(prefix + "Compactness 2 (voxel based)", compactness2Pixel)); featureList.push_back(std::make_pair(prefix + "Spherical disproportion (voxel based)", sphericalDisproportionPixel)); featureList.push_back(std::make_pair(prefix + "PCA Major axis length",major)); featureList.push_back(std::make_pair(prefix + "PCA Minor axis length",minor)); featureList.push_back(std::make_pair(prefix + "PCA Least axis length",least)); featureList.push_back(std::make_pair(prefix + "PCA Elongation",elongation)); featureList.push_back(std::make_pair(prefix + "PCA Flatness",flatness)); featureList.push_back(std::make_pair(prefix + "PCA Major axis length (uncorrected)", majorUC)); featureList.push_back(std::make_pair(prefix + "PCA Minor axis length (uncorrected)", minorUC)); featureList.push_back(std::make_pair(prefix + "PCA Least axis length (uncorrected)", leastUC)); featureList.push_back(std::make_pair(prefix + "PCA Elongation (uncorrected)", elongationUC)); featureList.push_back(std::make_pair(prefix + "PCA Flatness (uncorrected)", flatnessUC)); return featureList; }
std::vector<BaseData::Pointer> ItkImageIO::Read() { std::vector<BaseData::Pointer> result; const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } Image::Pointer image = Image::New(); const unsigned int MINDIM = 2; const unsigned int MAXDIM = 4; const std::string path = this->GetLocalFileName(); MITK_INFO << "loading " << path << " via itk::ImageIOFactory... " << std::endl; // Check to see if we can read the file given the name or prefix if (path.empty()) { mitkThrow() << "Empty filename in mitk::ItkImageIO "; } // Got to allocate space for the image. Determine the characteristics of // the image. m_ImageIO->SetFileName( path ); m_ImageIO->ReadImageInformation(); unsigned int ndim = m_ImageIO->GetNumberOfDimensions(); if ( ndim < MINDIM || ndim > MAXDIM ) { MITK_WARN << "Sorry, only dimensions 2, 3 and 4 are supported. The given file has " << ndim << " dimensions! Reading as 4D."; ndim = MAXDIM; } itk::ImageIORegion ioRegion( ndim ); itk::ImageIORegion::SizeType ioSize = ioRegion.GetSize(); itk::ImageIORegion::IndexType ioStart = ioRegion.GetIndex(); unsigned int dimensions[ MAXDIM ]; dimensions[ 0 ] = 0; dimensions[ 1 ] = 0; dimensions[ 2 ] = 0; dimensions[ 3 ] = 0; ScalarType spacing[ MAXDIM ]; spacing[ 0 ] = 1.0f; spacing[ 1 ] = 1.0f; spacing[ 2 ] = 1.0f; spacing[ 3 ] = 1.0f; Point3D origin; origin.Fill(0); unsigned int i; for ( i = 0; i < ndim ; ++i ) { ioStart[ i ] = 0; ioSize[ i ] = m_ImageIO->GetDimensions( i ); if(i<MAXDIM) { dimensions[ i ] = m_ImageIO->GetDimensions( i ); spacing[ i ] = m_ImageIO->GetSpacing( i ); if(spacing[ i ] <= 0) spacing[ i ] = 1.0f; } if(i<3) { origin[ i ] = m_ImageIO->GetOrigin( i ); } } ioRegion.SetSize( ioSize ); ioRegion.SetIndex( ioStart ); MITK_INFO << "ioRegion: " << ioRegion << std::endl; m_ImageIO->SetIORegion( ioRegion ); void* buffer = new unsigned char[m_ImageIO->GetImageSizeInBytes()]; m_ImageIO->Read( buffer ); image->Initialize( MakePixelType(m_ImageIO), ndim, dimensions ); image->SetImportChannel( buffer, 0, Image::ManageMemory ); // access direction of itk::Image and include spacing mitk::Matrix3D matrix; matrix.SetIdentity(); unsigned int j, itkDimMax3 = (ndim >= 3? 3 : ndim); for ( i=0; i < itkDimMax3; ++i) for( j=0; j < itkDimMax3; ++j ) matrix[i][j] = m_ImageIO->GetDirection(j)[i]; // re-initialize PlaneGeometry with origin and direction PlaneGeometry* planeGeometry = image->GetSlicedGeometry(0)->GetPlaneGeometry(0); planeGeometry->SetOrigin(origin); planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix); // re-initialize SlicedGeometry3D SlicedGeometry3D* slicedGeometry = image->GetSlicedGeometry(0); slicedGeometry->InitializeEvenlySpaced(planeGeometry, image->GetDimension(2)); slicedGeometry->SetSpacing(spacing); MITK_INFO << slicedGeometry->GetCornerPoint(false,false,false); MITK_INFO << slicedGeometry->GetCornerPoint(true,true,true); // re-initialize TimeGeometry ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); timeGeometry->Initialize(slicedGeometry, image->GetDimension(3)); image->SetTimeGeometry(timeGeometry); buffer = NULL; MITK_INFO << "number of image components: "<< image->GetPixelType().GetNumberOfComponents() << std::endl; const itk::MetaDataDictionary& dictionary = m_ImageIO->GetMetaDataDictionary(); for (itk::MetaDataDictionary::ConstIterator iter = dictionary.Begin(), iterEnd = dictionary.End(); iter != iterEnd; ++iter) { std::string key = std::string("meta.") + iter->first; if (iter->second->GetMetaDataObjectTypeInfo() == typeid(std::string)) { std::string value = dynamic_cast<itk::MetaDataObject<std::string>*>(iter->second.GetPointer())->GetMetaDataObjectValue(); image->SetProperty(key.c_str(), mitk::StringProperty::New(value)); } } MITK_INFO << "...finished!" << std::endl; try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } result.push_back(image.GetPointer()); return result; }