void CriminisiInpainting::InitializeConfidence()
{

  // Clone the mask - we need to invert the mask to actually perform the masking, but we don't want to disturb the original mask
  Mask::Pointer maskClone = Mask::New();
  //Helpers::DeepCopy<Mask>(this->CurrentMask, maskClone);
  maskClone->DeepCopyFrom(this->CurrentMask);
  
  // Invert the mask
  typedef itk::InvertIntensityImageFilter <Mask> InvertIntensityImageFilterType;

  InvertIntensityImageFilterType::Pointer invertIntensityFilter = InvertIntensityImageFilterType::New();
  invertIntensityFilter->SetInput(maskClone);
  //invertIntensityFilter->InPlaceOn();
  invertIntensityFilter->Update();

  // Convert the inverted mask to floats and scale them to between 0 and 1
  // to serve as the initial confidence image
  typedef itk::RescaleIntensityImageFilter< Mask, FloatScalarImageType > RescaleFilterType;
  RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();
  rescaleFilter->SetInput(invertIntensityFilter->GetOutput());
  rescaleFilter->SetOutputMinimum(0);
  rescaleFilter->SetOutputMaximum(1);
  rescaleFilter->Update();

  Helpers::DeepCopy<FloatScalarImageType>(rescaleFilter->GetOutput(), this->ConfidenceImage);
  //WriteImage<FloatImageType>(this->ConfidenceImage, "InitialConfidence.mhd");
}
예제 #2
0
void Mask::FindBoundary(UnsignedCharScalarImageType* boundaryImage) const
{
  // Compute the "outer" boundary of the region to fill. That is, we want the boundary pixels to be in the source region.

  //HelpersOutput::WriteImageConditional<Mask>(this->CurrentMask, "Debug/FindBoundary.CurrentMask.mha", this->DebugImages);
  //HelpersOutput::WriteImageConditional<Mask>(this->CurrentMask, "Debug/FindBoundary.CurrentMask.png", this->DebugImages);

  // Create a binary image (throw away the "dont use" pixels)
  Mask::Pointer holeOnly = Mask::New();
  holeOnly->DeepCopyFrom(this);

  itk::ImageRegionIterator<Mask> maskIterator(holeOnly, holeOnly->GetLargestPossibleRegion());
  // This should result in a white hole on a black background
  while(!maskIterator.IsAtEnd())
    {
    itk::Index<2> currentPixel = maskIterator.GetIndex();
    if(!holeOnly->IsHole(currentPixel))
      {
      holeOnly->SetPixel(currentPixel, holeOnly->GetValidValue());
      }
    ++maskIterator;
    }

  //HelpersOutput::WriteImageConditional<Mask>(holeOnly, "Debug/FindBoundary.HoleOnly.mha", this->DebugImages);
  //HelpersOutput::WriteImageConditional<Mask>(holeOnly, "Debug/FindBoundary.HoleOnly.png", this->DebugImages);

  // Since the hole is white, 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 <Mask, Mask> binaryContourImageFilterType;
  binaryContourImageFilterType::Pointer binaryContourFilter = binaryContourImageFilterType::New();
  binaryContourFilter->SetInput(holeOnly);
  binaryContourFilter->SetFullyConnected(true);
  binaryContourFilter->SetForegroundValue(holeOnly->GetValidValue());
  binaryContourFilter->SetBackgroundValue(holeOnly->GetHoleValue());
  binaryContourFilter->Update();

  //HelpersOutput::WriteImageConditional<Mask>(binaryContourFilter->GetOutput(), "Debug/FindBoundary.Boundary.mha", this->DebugImages);
  //HelpersOutput::WriteImageConditional<Mask>(binaryContourFilter->GetOutput(), "Debug/FindBoundary.Boundary.png", this->DebugImages);

  // Since we want to interpret non-zero pixels as boundary pixels, we must invert the image.
  typedef itk::InvertIntensityImageFilter <Mask> InvertIntensityImageFilterType;
  InvertIntensityImageFilterType::Pointer invertIntensityFilter = InvertIntensityImageFilterType::New();
  invertIntensityFilter->SetInput(binaryContourFilter->GetOutput());
  invertIntensityFilter->SetMaximum(255);
  invertIntensityFilter->Update();

  //this->BoundaryImage = binaryContourFilter->GetOutput();
  //this->BoundaryImage->Graft(binaryContourFilter->GetOutput());
  ITKHelpers::DeepCopy<UnsignedCharScalarImageType>(invertIntensityFilter->GetOutput(), boundaryImage);

  //HelpersOutput::WriteImageConditional<UnsignedCharScalarImageType>(this->BoundaryImage, "Debug/FindBoundary.BoundaryImage.mha", this->DebugImages);

}
  bool AcceptMatch(VertexDescriptorType target, VertexDescriptorType source, float& computedEnergy) const
  {
    //std::cout << "DilatedVarianceDifferenceAcceptanceVisitor::AcceptMatch" << std::endl;

    itk::Index<2> targetPixel = ITKHelpers::CreateIndex(target);
    itk::ImageRegion<2> targetRegion = ITKHelpers::GetRegionInRadiusAroundPixel(targetPixel, HalfWidth);

    itk::Index<2> sourcePixel = ITKHelpers::CreateIndex(source);
    itk::ImageRegion<2> sourceRegion = ITKHelpers::GetRegionInRadiusAroundPixel(sourcePixel, HalfWidth);

    // Compute the functor on the pixels in the region just inside the hole in the source patch
    typename TypeTraits<typename TImage::PixelType>::LargerType sourceValue;
    {
    Mask::Pointer originalHole = Mask::New();
    ITKHelpers::ExtractRegion(MaskImage, targetRegion, originalHole.GetPointer());

    Mask::Pointer shrunkHole = Mask::New();
    shrunkHole->DeepCopyFrom(originalHole);
    shrunkHole->ShrinkHole(5);

    typedef itk::Image<bool, 2> BoolImage;
    BoolImage::Pointer holeRindImage = BoolImage::New(); // "rind" like an "orange rind"
    ITKHelpers::XORRegions(originalHole.GetPointer(), originalHole->GetLargestPossibleRegion(),
                           shrunkHole.GetPointer(), shrunkHole->GetLargestPossibleRegion(), holeRindImage.GetPointer());

    std::vector<itk::Index<2> > holeRindPixels = ITKHelpers::GetPixelsWithValue(holeRindImage.GetPointer(), holeRindImage->GetLargestPossibleRegion(), true);

    itk::Index<2> zeroIndex = {{0,0}};
    std::vector<itk::Offset<2> > holeRindOffsets = ITKHelpers::IndicesToOffsets(holeRindPixels, zeroIndex);

    std::vector<itk::Index<2> > sourceRindPixelIndices = ITKHelpers::OffsetsToIndices(holeRindOffsets, sourceRegion.GetIndex());
    std::vector<typename TImage::PixelType> sourceRindPixels = ITKHelpers::GetPixelValues(Image, sourceRindPixelIndices);
    sourceValue = Functor(sourceRindPixels);
    }

    // Compute the functor on the pixels in the region just outside the hole in the target patch
    typename TypeTraits<typename TImage::PixelType>::LargerType targetValue;
    {
    Mask::Pointer originalHole = Mask::New();
    ITKHelpers::ExtractRegion(MaskImage, targetRegion, originalHole.GetPointer());

    Mask::Pointer expandedHole = Mask::New();
    expandedHole->DeepCopyFrom(originalHole);
    expandedHole->ExpandHole(5);

    typedef itk::Image<bool, 2> BoolImage;
    BoolImage::Pointer validRindImage = BoolImage::New(); // "rind" like an "orange rind"
    ITKHelpers::XORRegions(originalHole.GetPointer(), originalHole->GetLargestPossibleRegion(),
                           expandedHole.GetPointer(), expandedHole->GetLargestPossibleRegion(), validRindImage.GetPointer());

    std::vector<itk::Index<2> > validRindPixels = ITKHelpers::GetPixelsWithValue(validRindImage.GetPointer(), validRindImage->GetLargestPossibleRegion(), true);

    itk::Index<2> zeroIndex = {{0,0}};
    std::vector<itk::Offset<2> > validRindOffsets = ITKHelpers::IndicesToOffsets(validRindPixels, zeroIndex);

    std::vector<itk::Index<2> > targetRindPixelIndices = ITKHelpers::OffsetsToIndices(validRindOffsets, targetRegion.GetIndex());
    std::vector<typename TImage::PixelType> targetRindPixels = ITKHelpers::GetPixelValues(Image, targetRindPixelIndices);
    targetValue = Functor(targetRindPixels);
    }

    // Compute the difference
    computedEnergy = (targetValue - sourceValue).GetNorm();
    //std::cout << this->VisitorName << " Energy: " << computedEnergy << std::endl;

    if(computedEnergy < DifferenceThreshold)
      {
      std::cout << this->VisitorName << ": Match accepted (" << computedEnergy << " is less than " << DifferenceThreshold << ")" << std::endl << std::endl;
      return true;
      }
    else
      {
      std::cout << this->VisitorName << ": Match rejected (" << computedEnergy << " is greater than " << DifferenceThreshold << ")" << std::endl << std::endl;
      return false;
      }
  };