void Mask::ShrinkHole(const unsigned int kernelRadius) { UnsignedCharImageType::Pointer binaryHoleImage = UnsignedCharImageType::New(); this->CreateBinaryImage(binaryHoleImage, 255, 0); // std::cout << "binaryHoleImage: " << std::endl; // ITKHelpers::PrintImage(binaryHoleImage.GetPointer()); typedef itk::FlatStructuringElement<2> StructuringElementType; StructuringElementType::RadiusType radius; radius.Fill(kernelRadius); // This is correct that the RadiusType expects the region radius, not the side length. StructuringElementType structuringElement = StructuringElementType::Box(radius); typedef itk::BinaryErodeImageFilter<UnsignedCharImageType, UnsignedCharImageType, StructuringElementType> BinaryErodeImageFilterType; BinaryErodeImageFilterType::Pointer erodeFilter = BinaryErodeImageFilterType::New(); erodeFilter->SetInput(binaryHoleImage); erodeFilter->SetKernel(structuringElement); erodeFilter->Update(); // std::cout << "erodeFilter output: " << std::endl; // ITKHelpers::PrintImage(erodeFilter->GetOutput()); // There will now be more valid pixels than there were previously. Copy them into the mask. this->CreateValidPixelsFromValue(erodeFilter->GetOutput(), 0); }
void CriminisiInpainting::ExpandMask() { // Expand the mask - this is necessary to prevent the isophotes from being undefined in the target region typedef itk::FlatStructuringElement<2> StructuringElementType; StructuringElementType::RadiusType radius; radius.Fill(2); // Just a little bit of expansion //radius.Fill(this->PatchRadius[0]); // This was working, but huge expansion //radius.Fill(2.0* this->PatchRadius[0]); StructuringElementType structuringElement = StructuringElementType::Box(radius); typedef itk::BinaryDilateImageFilter<Mask, Mask, StructuringElementType> BinaryDilateImageFilterType; BinaryDilateImageFilterType::Pointer expandMaskFilter = BinaryDilateImageFilterType::New(); expandMaskFilter->SetInput(this->CurrentMask); expandMaskFilter->SetKernel(structuringElement); expandMaskFilter->Update(); if(this->DebugImages) { Helpers::WriteImage<Mask>(expandMaskFilter->GetOutput(), "Debug/ExpandMask.expandedMask.mha"); } //Helpers::DeepCopy<Mask>(expandMaskFilter->GetOutput(), this->CurrentMask); this->CurrentMask->DeepCopyFrom(expandMaskFilter->GetOutput()); //WriteScaledImage<Mask>(this->Mask, "expandedMask.mhd"); #if defined(INTERACTIVE) emit RefreshSignal(); #endif }
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 Mask::ExpandHole() { // Expand the mask - this is necessary to prevent the isophotes from being undefined in the target region typedef itk::FlatStructuringElement<2> StructuringElementType; StructuringElementType::RadiusType radius; radius.Fill(2); // Just a little bit of expansion //radius.Fill(this->PatchRadius[0]); // This was working, but huge expansion //radius.Fill(2.0* this->PatchRadius[0]); StructuringElementType structuringElement = StructuringElementType::Box(radius); typedef itk::BinaryDilateImageFilter<Mask, Mask, StructuringElementType> BinaryDilateImageFilterType; BinaryDilateImageFilterType::Pointer expandMaskFilter = BinaryDilateImageFilterType::New(); expandMaskFilter->SetInput(this); expandMaskFilter->SetKernel(structuringElement); expandMaskFilter->Update(); this->DeepCopyFrom(expandMaskFilter->GetOutput()); }
int main(int argc, char* argv[]) { // Setup CLI Module parsable interface mitkCommandLineParser parser; parser.setTitle("Connectedness Maps"); parser.setCategory("Features"); parser.setDescription("Computes connectedness maps"); parser.setContributor("MBI"); parser.setArgumentPrefix("--","-"); parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "input file"); parser.addArgument("seed", "s", mitkCommandLineParser::InputImage, "seed file"); parser.addArgument("mask", "m", mitkCommandLineParser::InputImage, "mask file"); parser.addArgument("mode", "t", mitkCommandLineParser::String, "Mode Feature | Vector | FeatureVector"); parser.addArgument("vector", "v", mitkCommandLineParser::InputImage, "Tensor Image (.dti)"); parser.addArgument("confidence", "c", mitkCommandLineParser::InputImage, "confidence map (only when Tensor Images are used)"); parser.addArgument("valueImage", "x", mitkCommandLineParser::InputImage, "image of values that are propagated"); parser.addArgument("erodeSeed", "a", mitkCommandLineParser::Bool, "apply erosion of seed region"); parser.addArgument("rankFilter", "r", mitkCommandLineParser::Bool, "median filter for propagation"); parser.addArgument("propMap", "p", mitkCommandLineParser::OutputFile, "[out] propagated map"); parser.addArgument("distanceMap", "d", mitkCommandLineParser::OutputFile, "[out] connectedness map"); parser.addArgument("euclidDistanceMap", "e", mitkCommandLineParser::OutputFile, "[out] euclid distance map"); // Parse input parameters map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv); // Show a help message if ( parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } bool useRank = false; bool applyErosion = false; bool useValueImage = false; if (parsedArgs.count("rankFilter") || parsedArgs.count("r")) useRank = true; if (parsedArgs.count("valueImage") || parsedArgs.count("x")) useValueImage = true; if (parsedArgs.count("erodeSeed") || parsedArgs.count("a")) applyErosion = true; std::string inputFile = us::any_cast<string>(parsedArgs["input"]); std::string propMap = us::any_cast<string>(parsedArgs["propMap"]); std::string conMap = us::any_cast<string>(parsedArgs["distanceMap"]); std::string tensImageFile = us::any_cast<string>(parsedArgs["vector"]); std::string maskFile = us::any_cast<string>(parsedArgs["mask"]); std::string mode = us::any_cast<string>(parsedArgs["mode"]); std::string seedFile = us::any_cast<string>(parsedArgs["seed"]); std::string confFile = us::any_cast<string>(parsedArgs["confidence"]); std::string euclidFile = us::any_cast<string>(parsedArgs["euclidDistanceMap"]); std::string valueImageFile = ""; if (useValueImage) valueImageFile = us::any_cast<string>(parsedArgs["valueImage"]); // Read-in image data mitk::Image::Pointer tmpImage; mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputFile); mitk::Image::Pointer maskImage = mitk::IOUtil::LoadImage(maskFile); mitk::Image::Pointer seedImage = mitk::IOUtil::LoadImage(seedFile); mitk::Image::Pointer valueImage; if (useValueImage) valueImage = mitk::IOUtil::LoadImage(valueImageFile); mitk::Image::Pointer confImage; if (mode == "Vector" || mode == "FeatureVector") { MITK_INFO << "Load Tensor/Confidence"; tmpImage= mitk::IOUtil::LoadImage(tensImageFile); confImage= mitk::IOUtil::LoadImage(confFile); } mitk::TensorImage* diffusionImage = static_cast<mitk::TensorImage*>(tmpImage.GetPointer()); // Convert all input data to ITK BinaryType::Pointer itkSeed = BinaryType::New(); BinaryType::Pointer itkMask = BinaryType::New(); ResultType::Pointer itkImage = ResultType::New(); ItkTensorImage::Pointer itkTensor = ItkTensorImage::New(); ResultType::Pointer itkWeight = ResultType::New(); ResultType::Pointer itkValueImage = ResultType::New(); mitk::CastToItkImage(inputImage, itkImage); mitk::CastToItkImage(maskImage, itkMask); mitk::CastToItkImage(seedImage, itkSeed); if (useValueImage) mitk::CastToItkImage(valueImage, itkValueImage); if (applyErosion) { typedef itk::FlatStructuringElement<3> StructuringElementType; StructuringElementType::RadiusType elementRadius; elementRadius.Fill(2); elementRadius[2] = 0; StructuringElementType structuringElement = StructuringElementType::Box(elementRadius); typedef itk::BinaryErodeImageFilter <BinaryType, BinaryType, StructuringElementType> BinaryErodeImageFilterType; BinaryErodeImageFilterType::Pointer erodeFilter = BinaryErodeImageFilterType::New(); erodeFilter->SetInput(itkSeed); erodeFilter->SetKernel(structuringElement); erodeFilter->SetForegroundValue(1); erodeFilter->Update(); itkSeed = erodeFilter->GetOutput(); } if (mode == "Vector" || mode == "FeatureVector") { mitk::CastToItkImage(diffusionImage, itkTensor); mitk::CastToItkImage(confImage, itkWeight); } // Setup filter itk::ConnectednessFilter<ResultType, BinaryType,float>::Pointer filter = itk::ConnectednessFilter<ResultType, BinaryType, float>::New(); filter->SetInputImage(itkImage); filter->SetInputSeed(itkSeed); filter->SetInputMask(itkMask); if (mode == "Vector") { filter->SetInputVectorField(itkTensor); filter->SetInputVectorFieldConfidenceMap(itkWeight); filter->SetMode(itk::ConnectednessFilter<ResultType, BinaryType,float>::VectorAgreement); } else if (mode == "FeatureVector") { filter->SetInputVectorField(itkTensor); filter->SetInputVectorFieldConfidenceMap(itkWeight); filter->SetMode(itk::ConnectednessFilter<ResultType, BinaryType,float>::FeatureVectorAgreement); } else filter->SetMode(itk::ConnectednessFilter<ResultType, BinaryType,float>::FeatureSimilarity); if (useValueImage) filter->SetPropagationImage(itkValueImage); filter->SetApplyRankFilter(useRank); filter->Update(); // Grab output and write results mitk::Image::Pointer result = mitk::Image::New(); mitk::GrabItkImageMemory(filter->GetOutput(), result); mitk::IOUtil::Save(result, propMap); mitk::Image::Pointer distance = mitk::Image::New(); mitk::GrabItkImageMemory(filter->GetDistanceImage().GetPointer(), distance); mitk::IOUtil::Save(distance, conMap); mitk::Image::Pointer euclidDistance = mitk::Image::New(); mitk::GrabItkImageMemory(filter->GetEuclideanDistanceImage().GetPointer(), euclidDistance); mitk::IOUtil::Save(euclidDistance, euclidFile); return EXIT_SUCCESS; }
void MaskNewGradientWithOriginalMask(std::string imageFilename, std::string maskFilename) { // Read image and convert it to grayscale ColorImageReaderType::Pointer imageReader = ColorImageReaderType::New(); imageReader->SetFileName(imageFilename); imageReader->Update(); UnsignedCharImageType::Pointer image = UnsignedCharImageType::New(); ColorToGrayscale<ColorImageType>(imageReader->GetOutput(), image); // Read mask image UnsignedCharImageReaderType::Pointer maskReader = UnsignedCharImageReaderType::New(); maskReader->SetFileName(maskFilename.c_str()); maskReader->Update(); // Blur the image to compute better gradient estimates typedef itk::DiscreteGaussianImageFilter< UnsignedCharImageType, FloatImageType > filterType; // Create and setup a Gaussian filter filterType::Pointer gaussianFilter = filterType::New(); gaussianFilter->SetInput(image); gaussianFilter->SetVariance(2); gaussianFilter->Update(); //WriteImage<FloatImageType>(gaussianFilter->GetOutput(), "gaussianBlur.mhd"); // this cannot be png because they are floats /* // Compute the gradient typedef itk::GradientImageFilter< FloatImageType, float, float> GradientFilterType; GradientFilterType::Pointer gradientFilter = GradientFilterType::New(); gradientFilter->SetInput(gaussianFilter->GetOutput()); gradientFilter->Update(); WriteImage<VectorImageType>(gradientFilter->GetOutput(), "gradient.mhd"); // this cannot be png because they are floats */ // Compute the gradient magnitude typedef itk::GradientMagnitudeImageFilter< FloatImageType, UnsignedCharImageType> GradientMagnitudeFilterType; GradientMagnitudeFilterType::Pointer gradientMagnitudeFilter = GradientMagnitudeFilterType::New(); gradientMagnitudeFilter->SetInput(gaussianFilter->GetOutput()); gradientMagnitudeFilter->Update(); WriteImage<UnsignedCharImageType>(gradientMagnitudeFilter->GetOutput(), "gradient.png"); // Expand the mask - this is necessary to prevent the isophotes from being undefined in the target region typedef itk::FlatStructuringElement<2> StructuringElementType; StructuringElementType::RadiusType radius; radius.Fill(5); StructuringElementType structuringElement = StructuringElementType::Box(radius); typedef itk::BinaryDilateImageFilter<UnsignedCharImageType, UnsignedCharImageType, StructuringElementType> BinaryDilateImageFilterType; BinaryDilateImageFilterType::Pointer expandMaskFilter = BinaryDilateImageFilterType::New(); expandMaskFilter->SetInput(maskReader->GetOutput()); expandMaskFilter->SetKernel(structuringElement); expandMaskFilter->Update(); UnsignedCharImageType::Pointer expandedMask = UnsignedCharImageType::New(); expandedMask->Graft(expandMaskFilter->GetOutput()); WriteScaledImage<UnsignedCharImageType>(expandedMask, "ExpandedMasked.png"); // Invert the mask typedef itk::InvertIntensityImageFilter <UnsignedCharImageType> InvertIntensityImageFilterType; InvertIntensityImageFilterType::Pointer invertMaskFilter = InvertIntensityImageFilterType::New(); invertMaskFilter->SetInput(expandedMask); invertMaskFilter->Update(); //WriteScaledImage<UnsignedCharImageType>(invertMaskFilter->GetOutput(), "invertedExpandedMask.mhd"); // Keep only values outside the masked region typedef itk::MaskImageFilter< UnsignedCharImageType, UnsignedCharImageType, UnsignedCharImageType > MaskFilterType; MaskFilterType::Pointer maskFilter = MaskFilterType::New(); maskFilter->SetInput(gradientMagnitudeFilter->GetOutput()); maskFilter->SetMaskImage(invertMaskFilter->GetOutput()); maskFilter->Update(); WriteScaledImage<UnsignedCharImageType>(maskFilter->GetOutput(), "MaskedGradientMagnitude.png"); }
//---------------------------------------------------------------------------- //---------------------------------------------------------------------------- int main(int argc, char**argv) { int width, height, depth, xysize, compress, err; float peelsize; float ball_radius; char *inputFile, *erodedFile, *binFile; bool compressdata = true; bool make_binFile; if (argc != 5 && argc != 6) { printf("Usage: erode input_tiff eroded_tiff data_file ball_radius compress_data\n"); printf("or\n"); printf("Usage: erode input_tiff eroded_tiff ball_radius compress_data\n"); return 0; } inputFile = argv[1]; erodedFile = argv[2]; if (argc == 6) { make_binFile = true; binFile = argv[3]; sscanf(argv[4],"%f",&ball_radius); sscanf(argv[5],"%d",&compress); } else { make_binFile = false; sscanf(argv[3],"%f",&ball_radius); sscanf(argv[4],"%d",&compress); } compressdata = (compress == 1); printf("Input image file: %s\n",inputFile); printf("Eroded image file: %s\n",erodedFile); if (make_binFile) printf("Hull binary data file: %s\n",binFile); printf("Ball radius: %f\n",ball_radius); printf("compressdata: %d\n",compressdata); typedef itk::ImageFileReader<ImageType> FileReaderType; FileReaderType::Pointer reader = FileReaderType::New(); reader->SetFileName(inputFile); try { reader->Update(); } catch (itk::ExceptionObject &e) { std::cout << e << std::endl; return 1; } inputImage = reader->GetOutput(); width = inputImage->GetLargestPossibleRegion().GetSize()[0]; height = inputImage->GetLargestPossibleRegion().GetSize()[1]; depth = inputImage->GetLargestPossibleRegion().GetSize()[2]; xysize = width*height; printf("Image dimensions: width, height, depth: %d %d %d\n",width,height,depth); /* typedef itk::BinaryThresholdImageFilter<ImageType, ImageType> ThresholdFilterType; ThresholdFilterType::Pointer Thresh = ThresholdFilterType::New(); if (threshold > 0) { printf("Thresholding\n"); Thresh->SetInput(inputImage); Thresh->SetUpperThreshold(threshold); Thresh->SetOutsideValue(1); Thresh->SetInsideValue(0); Thresh->ReleaseDataFlagOn(); //err = ImWriter(Thresh->GetOutput(),"thresh.tif"); //if (err != 0) { // printf("ImWriter error on threshold file\n"); // return 1; //} } printf("Closing\n"); typedef itk::BinaryCloseParaImageFilter<ImageType, ImageType> BinCloseFilterType; BinCloseFilterType::Pointer BinClose = BinCloseFilterType::New(); if (threshold > 0) { BinClose->SetInput(Thresh->GetOutput()); } else { BinClose->SetInput(inputImage); } BinClose->SetUseImageSpacing(true); BinClose->SetRadius(ballsize); BinClose->ReleaseDataFlagOn(); // err = ImWriter(BinClose->GetOutput(),"close1.tif"); //if (err != 0) { // printf("ImWriter error on close1 file\n"); // return 1; //} printf("Scaling\n"); typedef itk::ShiftScaleImageFilter<ImageType, ImageType> ScaleFilterType; ScaleFilterType::Pointer Scale = ScaleFilterType::New(); Scale->SetInput(BinClose->GetOutput()); Scale->SetScale(255.0); */ // const unsigned int radiusValue = peelsize/2; typedef itk::FlatStructuringElement< 3 > StructuringElementType; StructuringElementType::RadiusType radius; radius.Fill( ball_radius ); StructuringElementType structuringElement = StructuringElementType::Ball( radius ); typedef itk::BinaryErodeImageFilter< ImageType, ImageType, StructuringElementType > BinaryErodeImageFilterType; BinaryErodeImageFilterType::Pointer erodeFilter = BinaryErodeImageFilterType::New(); erodeFilter->SetInput( reader->GetOutput() ); erodeFilter->SetKernel( structuringElement ); printf("Writing eroded tiff\n"); err = ImWriter(erodeFilter->GetOutput(),erodedFile); if (err != 0) { printf("ImWriter error on eroded file\n"); return 1; } if (make_binFile) { printf("Writing close binary data file\n"); p = (unsigned char *)(erodeFilter->GetOutput()->GetBufferPointer()); err = BinImWriter(binFile,p,width,height,depth,compressdata); if (err != 0) { printf("BinImWriter error on binary file\n"); return 2; } } return 0; }