void Mask::CreateBoundaryImageInRegion(const itk::ImageRegion<2>& region, BoundaryImageType* const boundaryImage, const HoleMaskPixelTypeEnum& whichSideOfBoundary) const { // Create a binary image of the mask unsigned char holeColor = 255; unsigned char validColor = 0; UnsignedCharImageType::Pointer fullBinaryImage = UnsignedCharImageType::New(); CreateBinaryImageInRegion(region, fullBinaryImage, holeColor, validColor); // Extract the relevant region from the binary image UnsignedCharImageType::Pointer binaryImage = UnsignedCharImageType::New(); binaryImage->SetRegions(region); binaryImage->Allocate(); CopyRegion(fullBinaryImage.GetPointer(), binaryImage.GetPointer(), region, region); // Extract the relevant region from the mask Mask::Pointer extractedRegionMask = Mask::New(); extractedRegionMask->SetRegions(region); extractedRegionMask->Allocate(); CopyRegion(this, extractedRegionMask.GetPointer(), region, region); // Since the hole is white (we have specified this at the beginning of this function), // we want the foreground value of the contour filter to be black. // This means that the boundary will be detected in the black pixel region, // which is on the outside edge of the hole like we want. However, // The BinaryContourImageFilter will change all non-boundary pixels to the background color, // so the resulting output will be inverted - the boundary pixels will be black and the // non-boundary pixels will be white. // Find the boundary typedef itk::BinaryContourImageFilter<UnsignedCharImageType, UnsignedCharImageType> binaryContourImageFilterType; binaryContourImageFilterType::Pointer binaryContourFilter = binaryContourImageFilterType::New(); binaryContourFilter->SetInput(binaryImage); binaryContourFilter->SetFullyConnected(true); if(whichSideOfBoundary == HoleMaskPixelTypeEnum::VALID) { // we want the boundary pixels to be in the valid region. binaryContourFilter->SetForegroundValue(validColor); binaryContourFilter->SetBackgroundValue(holeColor); } else if(whichSideOfBoundary == HoleMaskPixelTypeEnum::HOLE) { // we want the boundary pixels to be in the hole region. binaryContourFilter->SetForegroundValue(holeColor); binaryContourFilter->SetBackgroundValue(validColor); } else { throw std::runtime_error("An invalid side of the boundary was requested."); } binaryContourFilter->Update(); DeepCopy(binaryContourFilter->GetOutput(), boundaryImage); }
bool TestSamePatch(ColorImageType::Pointer image, UnsignedCharImageType::Pointer mask) { itk::Index<2> queryPixel; queryPixel[0] = 10; queryPixel[1] = 10; itk::Index<2> fixedPixel; fixedPixel[0] = 10; fixedPixel[1] = 10; unsigned int patchRadius = 5; float difference = PatchDifference(image.GetPointer(), mask.GetPointer(), queryPixel, fixedPixel, patchRadius); std::cerr << "Difference: " << difference << std::endl; if(difference != 0) { std::cerr << "Error: the difference between the same pixel should be zero!" << std::endl; return false; } return true; }
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"); }