template <class ImagePixelType, class MaskPixelType> int update() { typedef itk::Image<ImagePixelType, 3> ImageType; typedef itk::Image<MaskPixelType, 3> MaskType; if ( !input ||!input->data() || !mask ||!mask->data()) return EXIT_FAILURE; typedef itk::MaskImageFilter< ImageType, MaskType> MaskFilterType; typename MaskFilterType::Pointer maskFilter = MaskFilterType::New(); typename ImageType::Pointer imgInput = dynamic_cast<ImageType *> ( ( itk::Object* ) ( input->data() )) ; typename MaskType::Pointer maskInput = dynamic_cast<MaskType *> ( ( itk::Object* ) ( mask->data() )) ; try { maskInput->SetOrigin(imgInput->GetOrigin()); maskInput->SetSpacing(imgInput->GetSpacing()); maskFilter->SetInput(imgInput); maskFilter->SetMaskingValue(maskBackgroundValue); maskFilter->SetMaskImage(maskInput); //Outside values set to the lowest reachable value typedef itk::MinimumMaximumImageCalculator <ImageType> ImageCalculatorFilterType; typename ImageCalculatorFilterType::Pointer imageCalculatorFilter = ImageCalculatorFilterType::New (); imageCalculatorFilter->SetImage(imgInput); imageCalculatorFilter->ComputeMinimum(); maskFilter->SetOutsideValue(std::min(double(imageCalculatorFilter->GetMinimum()), 0.0)); maskFilter->Update(); output->setData(maskFilter->GetOutput()); } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught in medMaskApplication!" << std::endl; std::cerr << err << std::endl; return EXIT_FAILURE; } medUtilities::setDerivedMetaData(output, input, "masked"); return EXIT_SUCCESS; }
void BoundaryNormals::ComputeBoundaryNormals(TNormalsImage* const boundaryNormalsImage, const float maskBlurVariance) { // Blur the mask, compute the gradient, then keep the normals only at the original mask boundary // Compute the boundary of the mask typedef itk::Image<unsigned char, 2> BoundaryImageType; BoundaryImageType::Pointer boundaryImage = BoundaryImageType::New(); this->MaskImage->CreateBoundaryImage(boundaryImage, Mask::VALID, 255); if(this->IsDebugOn()) { ITKHelpers::WriteImage(boundaryImage.GetPointer(), "ComputeBoundaryNormals.BoundaryImage.mha"); } // Blur the mask so that the normals are not quantized so much. Also, pixels with only diagonal // valid neighbors have undefined gradients without this blurring. typedef itk::DiscreteGaussianImageFilter<Mask, ITKHelpers::FloatScalarImageType> BlurFilterType; BlurFilterType::Pointer gaussianFilter = BlurFilterType::New(); gaussianFilter->SetInput(this->MaskImage); gaussianFilter->SetVariance(maskBlurVariance); gaussianFilter->Update(); if(this->IsDebugOn()) { ITKHelpers::WriteImage(gaussianFilter->GetOutput(), "ComputeBoundaryNormals.BlurredMask.mha"); } // Compute the gradient of the blurred mask typedef itk::GradientImageFilter<ITKHelpers::FloatScalarImageType, float, float> GradientFilterType; GradientFilterType::Pointer gradientFilter = GradientFilterType::New(); gradientFilter->SetInput(gaussianFilter->GetOutput()); gradientFilter->Update(); if(this->IsDebugOn()) { ITKHelpers::WriteImage(gradientFilter->GetOutput(), "ComputeBoundaryNormals.BlurredMaskGradient.mha"); } // Only keep the normals at the boundary typedef itk::MaskImageFilter<TNormalsImage, ITKHelpers::UnsignedCharScalarImageType, TNormalsImage> MaskFilterType; typename MaskFilterType::Pointer maskFilter = MaskFilterType::New(); maskFilter->SetInput(gradientFilter->GetOutput()); maskFilter->SetMaskImage(boundaryImage); maskFilter->Update(); if(this->IsDebugOn()) { ITKHelpers::WriteImage(maskFilter->GetOutput(), "ComputeBoundaryNormals.BoundaryNormalsUnnormalized.mha"); } // Allocate the image to return // ITKHelpers::DeepCopy(maskFilter->GetOutput(), boundaryNormalsImage); ITKHelpers::InitializeImage(boundaryNormalsImage, this->MaskImage->GetLargestPossibleRegion()); // Normalize the vectors because we just care about their direction std::vector<itk::Index<2> > boundaryPixels = ITKHelpers::GetNonZeroPixels(boundaryImage.GetPointer()); for(std::vector<itk::Index<2> >::const_iterator boundaryPixelIterator = boundaryPixels.begin(); boundaryPixelIterator != boundaryPixels.end(); ++boundaryPixelIterator) { typename TNormalsImage::PixelType p = maskFilter->GetOutput()->GetPixel(*boundaryPixelIterator); p.Normalize(); boundaryNormalsImage->SetPixel(*boundaryPixelIterator, p); } }