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"); }
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; } };