Example #1
0
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");
}