void Cell::ComputeMaskedImage() { typedef itk::MaskNegatedImageFilter< ImageType, MaskImageType, ImageType > MaskFilterType; MaskFilterType::Pointer maskFilter = MaskFilterType::New(); maskFilter->SetMaskImage(this->mask); maskFilter->SetInput(this->image); try { //ftk::TimeStampOverflowSafeUpdate( maskFilter.GetPointer() ); maskFilter->Update(); } catch (itk::ExceptionObject &err) { std::cerr << "maskFilter Exception: " << err << std::endl; } this->masked_image = maskFilter->GetOutput(); this->masked_image->DisconnectPipeline(); //Disconnect pipeline so we don't propagate... //Make the file name of the masked cell image std::stringstream masked_cell_filename_stream; masked_cell_filename_stream << cell_x << "_" << cell_y << "_" << cell_z << "_masked.TIF"; //X_Y_Z_masked.TIF //Write the masked cell image //WriteImage(masked_cell_filename_stream.str(), this->masked_image); }
int main(int argc, char *argv[]) { if(argc != 3) { std::cerr << "Required arguments: image mask" << std::endl; return EXIT_FAILURE; } std::string imageFilename = argv[1]; std::string maskFilename = argv[2]; std::cout << "Reading image: " << imageFilename << std::endl; std::cout << "Reading mask: " << maskFilename << std::endl; typedef itk::ImageFileReader<FloatVectorImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename.c_str()); imageReader->Update(); std::cout << "Read image " << imageReader->GetOutput()->GetLargestPossibleRegion() << std::endl; typedef itk::ImageFileReader<Mask> MaskReaderType; MaskReaderType::Pointer maskReader = MaskReaderType::New(); maskReader->SetFileName(maskFilename.c_str()); maskReader->Update(); std::cout << "Read mask " << maskReader->GetOutput()->GetLargestPossibleRegion() << std::endl; // Prepare image RGBImageType::Pointer rgbImage = RGBImageType::New(); // Helpers::VectorImageToRGBImage(imageReader->GetOutput(), rgbImage); // TODO: Update this call to new API //maskReader->GetOutput()->ApplyToImage(rgbImage.GetPointer(), Qt::black); OutputHelpers::WriteImage<RGBImageType>(rgbImage, "Test/TestIsophotes.rgb.mha"); typedef itk::RGBToLuminanceImageFilter< RGBImageType, FloatScalarImageType > LuminanceFilterType; LuminanceFilterType::Pointer luminanceFilter = LuminanceFilterType::New(); luminanceFilter->SetInput(rgbImage); luminanceFilter->Update(); OutputHelpers::WriteImage<FloatScalarImageType>(luminanceFilter->GetOutput(), "Test/Luminance.mha"); // PatchBasedInpainting inpainting; // inpainting.SetDebugImages(true); // inpainting.SetMask(maskReader->GetOutput()); // inpainting.SetImage(imageReader->GetOutput()); //Helpers::Write2DVectorImage(inpainting.GetIsophoteImage(), "Test/TestIsophotes.isophotes.mha"); //inpainting.FindBoundary(); // After blurVariance == 4, you cannot tell the difference in the output. for(unsigned int blurVariance = 0; blurVariance < 5; ++blurVariance) { std::string fileNumber = Helpers::ZeroPad(blurVariance, 2); FloatScalarImageType::Pointer blurredLuminance = FloatScalarImageType::New(); // Blur with a Gaussian kernel MaskOperations::MaskedBlur(luminanceFilter->GetOutput(), maskReader->GetOutput(), blurVariance, blurredLuminance.GetPointer()); std::stringstream ssBlurredLuminance; ssBlurredLuminance << "Test/BlurredLuminance_" << fileNumber << ".mha"; OutputHelpers::WriteImage(blurredLuminance.GetPointer(), ssBlurredLuminance.str()); //Helpers::WriteImage<FloatScalarImageType>(blurredLuminance, "Test/TestIsophotes.blurred.mha"); FloatVector2ImageType::Pointer gradient = FloatVector2ImageType::New(); Derivatives::MaskedGradient(blurredLuminance.GetPointer(), maskReader->GetOutput(), gradient.GetPointer()); // Boundary gradient typedef itk::MaskImageFilter< FloatVector2ImageType, UnsignedCharScalarImageType, FloatVector2ImageType > MaskFilterType; MaskFilterType::Pointer maskFilter = MaskFilterType::New(); maskFilter->SetInput(gradient); //maskFilter->SetMaskImage(inpainting.GetBoundaryImage()); maskFilter->Update(); vtkSmartPointer<vtkPolyData> boundaryGradient = vtkSmartPointer<vtkPolyData>::New(); // TODO: Convert this call to new API //Helpers::ConvertNonZeroPixelsToVectors(maskFilter->GetOutput(), boundaryGradient); std::stringstream ssPolyData; ssPolyData << "Test/BoundaryGradient_" << fileNumber << ".vtp"; OutputHelpers::WritePolyData(boundaryGradient, ssPolyData.str()); } return EXIT_SUCCESS; }
void CriminisiInpainting::ComputeBoundaryNormals() { try { // Blur the mask, compute the gradient, then keep the normals only at the original mask boundary if(this->DebugImages) { Helpers::WriteImage<UnsignedCharScalarImageType>(this->BoundaryImage, "Debug/ComputeBoundaryNormals.BoundaryImage.mha"); Helpers::WriteImage<Mask>(this->CurrentMask, "Debug/ComputeBoundaryNormals.CurrentMask.mha"); } // Blur the mask typedef itk::DiscreteGaussianImageFilter< Mask, FloatScalarImageType > BlurFilterType; BlurFilterType::Pointer gaussianFilter = BlurFilterType::New(); gaussianFilter->SetInput(this->CurrentMask); gaussianFilter->SetVariance(2); gaussianFilter->Update(); if(this->DebugImages) { Helpers::WriteImage<FloatScalarImageType>(gaussianFilter->GetOutput(), "Debug/ComputeBoundaryNormals.BlurredMask.mha"); } // Compute the gradient of the blurred mask typedef itk::GradientImageFilter< FloatScalarImageType, float, float> GradientFilterType; GradientFilterType::Pointer gradientFilter = GradientFilterType::New(); gradientFilter->SetInput(gaussianFilter->GetOutput()); gradientFilter->Update(); if(this->DebugImages) { Helpers::WriteImage<FloatVector2ImageType>(gradientFilter->GetOutput(), "Debug/ComputeBoundaryNormals.BlurredMaskGradient.mha"); } // Only keep the normals at the boundary typedef itk::MaskImageFilter< FloatVector2ImageType, UnsignedCharScalarImageType, FloatVector2ImageType > MaskFilterType; MaskFilterType::Pointer maskFilter = MaskFilterType::New(); //maskFilter->SetInput1(gradientFilter->GetOutput()); //maskFilter->SetInput2(this->BoundaryImage); maskFilter->SetInput(gradientFilter->GetOutput()); maskFilter->SetMaskImage(this->BoundaryImage); maskFilter->Update(); if(this->DebugImages) { Helpers::WriteImage<FloatVector2ImageType>(maskFilter->GetOutput(), "Debug/ComputeBoundaryNormals.BoundaryNormalsUnnormalized.mha"); } //this->BoundaryNormals = maskFilter->GetOutput(); //this->BoundaryNormals->Graft(maskFilter->GetOutput()); Helpers::DeepCopy<FloatVector2ImageType>(maskFilter->GetOutput(), this->BoundaryNormals); // Normalize the vectors because we just care about their direction (the Data term computation calls for the normalized boundary normal) itk::ImageRegionIterator<FloatVector2ImageType> boundaryNormalsIterator(this->BoundaryNormals, this->BoundaryNormals->GetLargestPossibleRegion()); itk::ImageRegionConstIterator<UnsignedCharScalarImageType> boundaryIterator(this->BoundaryImage, this->BoundaryImage->GetLargestPossibleRegion()); while(!boundaryNormalsIterator.IsAtEnd()) { if(boundaryIterator.Get()) // The pixel is on the boundary { FloatVector2ImageType::PixelType p = boundaryNormalsIterator.Get(); p.Normalize(); boundaryNormalsIterator.Set(p); } ++boundaryNormalsIterator; ++boundaryIterator; } if(this->DebugImages) { Helpers::WriteImage<FloatVector2ImageType>(this->BoundaryNormals, "Debug/ComputeBoundaryNormals.BoundaryNormals.mha"); } } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught in ComputeBoundaryNormals!" << std::endl; std::cerr << err << std::endl; exit(-1); } }
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"); }