void CriminisiInpainting::UpdateMask(const itk::Index<2> inputPixel) { try { // Create a black patch Mask::Pointer blackPatch = Mask::New(); //Helpers::CreateBlankPatch<UnsignedCharScalarImageType>(blackPatch, this->PatchRadius[0]); Helpers::CreateConstantPatch<Mask>(blackPatch, this->CurrentMask->GetValidValue(), this->PatchRadius[0]); itk::Index<2> pixel; pixel[0] = inputPixel[0] - blackPatch->GetLargestPossibleRegion().GetSize()[0]/2; pixel[1] = inputPixel[1] - blackPatch->GetLargestPossibleRegion().GetSize()[1]/2; // Paste it into the mask typedef itk::PasteImageFilter <Mask, Mask> PasteImageFilterType; PasteImageFilterType::Pointer pasteFilter = PasteImageFilterType::New(); //pasteFilter->SetInput(0, this->CurrentMask); //pasteFilter->SetInput(1, blackPatch); pasteFilter->SetSourceImage(blackPatch); pasteFilter->SetDestinationImage(this->CurrentMask); pasteFilter->SetSourceRegion(blackPatch->GetLargestPossibleRegion()); pasteFilter->SetDestinationIndex(pixel); pasteFilter->Update(); // Not sure how Mask::DeepCopyFrom would work on the output of a filter, so do this manually. Helpers::DeepCopy<Mask>(pasteFilter->GetOutput(), this->CurrentMask); this->CurrentMask->SetHoleValue(this->OriginalMask->GetHoleValue()); this->CurrentMask->SetValidValue(this->OriginalMask->GetValidValue()); } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught in UpdateMask!" << std::endl; std::cerr << err << std::endl; exit(-1); } }
int main(int argc, char*argv[]) { if(argc != 3) { std::cerr << "Required arguments: mask output" << std::endl; return EXIT_FAILURE; } std::string maskFilename = argv[1]; std::string outputFilename = argv[2]; std::cout << "Reading mask: " << maskFilename << std::endl; std::cout << "Output: " << outputFilename << std::endl; Mask::Pointer mask = Mask::New(); mask->Read(maskFilename.c_str()); Mask::BoundaryImageType::Pointer boundaryImage = Mask::BoundaryImageType::New(); boundaryImage->SetRegions(mask->GetLargestPossibleRegion()); boundaryImage->Allocate(); // mask->CreateBoundaryImage(boundaryImage.GetPointer(), mask->GetValidValue()); mask->CreateBoundaryImage(boundaryImage.GetPointer(), Mask::VALID); ITKHelpers::WriteImage(boundaryImage.GetPointer(), outputFilename); return EXIT_SUCCESS; }
static void CreateMask(Mask::Pointer mask) { itk::Size<2> size; size.Fill(20); itk::Index<2> start; start.Fill(0); itk::ImageRegion<2> region(start,size); mask->SetRegions(region); mask->Allocate(); mask->FillBuffer(mask->GetValidValue()); itk::ImageRegionIterator<Mask> iterator(mask, mask->GetLargestPossibleRegion()); while(!iterator.IsAtEnd()) { if(iterator.GetIndex()[0] > 5 && iterator.GetIndex()[0] < 15 && iterator.GetIndex()[1] > 5 && iterator.GetIndex()[1] < 15) { mask->SetPixel(iterator.GetIndex(), mask->GetHoleValue()); } ++iterator; } }
// Run with: image.png image.mask 15 filled.png int main(int argc, char *argv[]) { // Verify arguments if(argc != 5) { std::cerr << "Required arguments: image.png image.mask patchHalfWidth output.png" << std::endl; std::cerr << "Input arguments: "; for(int i = 1; i < argc; ++i) { std::cerr << argv[i] << " "; } return EXIT_FAILURE; } // Parse arguments std::string imageFilename = argv[1]; std::string maskFilename = argv[2]; std::stringstream ssPatchRadius; ssPatchRadius << argv[3]; unsigned int patchHalfWidth = 0; ssPatchRadius >> patchHalfWidth; std::string outputFilename = argv[4]; // Output arguments std::cout << "Reading image: " << imageFilename << std::endl; std::cout << "Reading mask: " << maskFilename << std::endl; std::cout << "Patch half width: " << patchHalfWidth << std::endl; std::cout << "Output: " << outputFilename << std::endl; typedef itk::Image<itk::CovariantVector<float, 3>, 2> ImageType; typedef itk::ImageFileReader<ImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename); imageReader->Update(); ImageType::Pointer image = ImageType::New(); ITKHelpers::DeepCopy(imageReader->GetOutput(), image.GetPointer()); Mask::Pointer mask = Mask::New(); mask->Read(maskFilename); std::cout << "Mask size: " << mask->GetLargestPossibleRegion().GetSize() << std::endl; std::cout << "hole pixels: " << mask->CountHolePixels() << std::endl; std::cout << "valid pixels: " << mask->CountValidPixels() << std::endl; // Setup the GUI system QApplication app( argc, argv ); // Without this, after we close the first dialog // (after the first iteration that is not accepted automatically), the event loop quits. app.setQuitOnLastWindowClosed(false); DummyPatchesDriver(image, mask, patchHalfWidth); return app.exec(); }
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); }
int main(int argc, char*argv[]) { if(argc < 4) { std::cerr << "Required arguments: image mask output" << std::endl; return EXIT_FAILURE; } std::string imageFilename = argv[1]; std::string maskFilename = argv[2]; std::string outputFilename = argv[3]; std::cout << "imageFilename: " << imageFilename << std::endl; std::cout << "maskFilename: " << maskFilename << std::endl; std::cout << "outputFilename: " << outputFilename << std::endl; typedef itk::ImageFileReader<ImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename); imageReader->Update(); Mask::Pointer sourceMask = Mask::New(); sourceMask->Read(maskFilename); Mask::Pointer targetMask = Mask::New(); targetMask->SetRegions(sourceMask->GetLargestPossibleRegion()); targetMask->Allocate(); ITKHelpers::SetImageToConstant(targetMask.GetPointer(), HoleMaskPixelTypeEnum::VALID); typedef SSD<ImageType> DistanceFunctorType; DistanceFunctorType* patchDistanceFunctor = new DistanceFunctorType; patchDistanceFunctor->SetImage(imageReader->GetOutput()); typedef Propagator<DistanceFunctorType> PropagatorType; PropagatorType* propagationFunctor = new PropagatorType; typedef RandomSearch<ImageType, DistanceFunctorType> RandomSearchType; RandomSearchType* randomSearchFunctor = new RandomSearchType; typedef PatchMatch<ImageType, PropagatorType, RandomSearchType> PatchMatchType; PatchMatchType patchMatch; patchMatch.SetImage(imageReader->GetOutput()); patchMatch.SetPatchRadius(3); patchMatch.SetPropagationFunctor(propagationFunctor); patchMatch.SetRandomSearchFunctor(randomSearchFunctor); patchMatch.Compute(); NNFieldType::Pointer output = patchMatch.GetNNField(); PatchMatchHelpers::WriteNNField(output.GetPointer(), "nnfield.mha"); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { // Verify arguments if(argc != 5) { std::cerr << "Required arguments: image imageMask patchRadius outputPrefix" << std::endl; return EXIT_FAILURE; } // Parse arguments std::string imageFilename = argv[1]; std::string maskFilename = argv[2]; std::stringstream ssPatchRadius; ssPatchRadius << argv[3]; int patchRadius = 0; ssPatchRadius >> patchRadius; std::string outputPrefix = argv[4]; // Output arguments std::cout << "Reading image: " << imageFilename << std::endl; std::cout << "Reading mask: " << maskFilename << std::endl; std::cout << "Patch radius: " << patchRadius << std::endl; //std::cout << "Output: " << outputFilename << std::endl; typedef itk::ImageFileReader< FloatVectorImageType > ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename.c_str()); imageReader->Update(); FloatVectorImageType::Pointer scaledImage = FloatVectorImageType::New(); // Initialize Helpers::DeepCopy<FloatVectorImageType>(imageReader->GetOutput(), scaledImage); std::vector<float> maxValues = Helpers::MaxValuesVectorImage<float>(imageReader->GetOutput()); // Scale all channels the same // for(unsigned int channel = 0; channel < imageReader->GetOutput()->GetNumberOfComponentsPerPixel(); ++channel) // { // Helpers::ScaleChannel<float>(imageReader->GetOutput(), channel, 1.0f, scaledImage); // } // Scale color channels for(unsigned int channel = 0; channel < 3; ++channel) { Helpers::ScaleChannel<float>(scaledImage, channel, 0.33f, scaledImage); } // Scale depth channel Helpers::ScaleChannel<float>(scaledImage, 3, 1.0f, scaledImage); Helpers::WriteImage<FloatVectorImageType>(scaledImage, "scaled.mha"); typedef itk::ImageFileReader< Mask > MaskReaderType; MaskReaderType::Pointer maskReader = MaskReaderType::New(); maskReader->SetFileName(maskFilename.c_str()); maskReader->Update(); Mask::Pointer finalMask = Mask::New(); ModifyMask(maskReader->GetOutput(), patchRadius, finalMask); cout.setf(ios::showpoint); std::vector<float> lambdas; for(unsigned int i = 0; i <= 10; ++i) { lambdas.push_back(0.1f * static_cast<float>(i)); std::cout << "Using lambda " << lambdas[i] << std::endl; } std::shared_ptr<SelfPatchCompare> patchCompare(new SelfPatchCompare); patchCompare->SetNumberOfComponentsPerPixel(imageReader->GetOutput()->GetNumberOfComponentsPerPixel()); //patchCompare->FunctionsToCompute.push_back(boost::bind(&SelfPatchCompare::SetPatchAverageAbsoluteSourceDifference,patchCompare,_1)); patchCompare->FunctionsToCompute.push_back(boost::bind(&SelfPatchCompare::SetPatchColorDifference,patchCompare,_1)); patchCompare->FunctionsToCompute.push_back(boost::bind(&SelfPatchCompare::SetPatchDepthDifference,patchCompare,_1)); std::ofstream fout("scores.txt"); fout.setf(ios::showpoint); for(unsigned int lambdaId = 0; lambdaId < lambdas.size(); ++lambdaId) { // Inpaint std::cout << "Inpainting with lambda = " << lambdas[lambdaId] << std::endl; PatchPair::DepthColorLambda = lambdas[lambdaId]; CriminisiInpainting inpainting; //inpainting.SetDebugFunctionEnterLeave(true); inpainting.SetPatchRadius(patchRadius); inpainting.SetImage(scaledImage); inpainting.SetMask(finalMask); inpainting.SetMaxForwardLookPatches(3); inpainting.SetPatchCompare(patchCompare); inpainting.PatchSortFunction = &SortByDepthAndColor; //inpainting.PatchSortFunction = &SortByAverageAbsoluteDifference; //DepthAndColorDifference = ColorDifference * Lambda + (1.0 - Lambda) * DepthDifference; // When lambda = 0, only the depth is used // When lambda = 1, only the color is used inpainting.Initialize(); inpainting.Inpaint(); // Compute error itk::ImageRegionIterator<Mask> iterator(finalMask, finalMask->GetLargestPossibleRegion()); float depthError = 0.0f; float colorError = 0.0f; while(!iterator.IsAtEnd()) { if(finalMask->IsHole(iterator.GetIndex())) { colorError += ColorPixelDifference::Difference(scaledImage->GetPixel(iterator.GetIndex()), inpainting.GetCurrentOutputImage()->GetPixel(iterator.GetIndex())); depthError += DepthPixelDifference::Difference(scaledImage->GetPixel(iterator.GetIndex()), inpainting.GetCurrentOutputImage()->GetPixel(iterator.GetIndex())); } ++iterator; } std::cout << "colorError: " << colorError << std::endl; std::cout << "depthError: " << depthError << std::endl; fout << colorError << " " << depthError << std::endl; // Unscale all channels for(unsigned int channel = 0; channel < imageReader->GetOutput()->GetNumberOfComponentsPerPixel(); ++channel) { Helpers::ScaleChannel<float>(inpainting.GetCurrentOutputImage(), channel, maxValues[channel], inpainting.GetCurrentOutputImage()); } std::stringstream ssFloat; ssFloat.setf(ios::showpoint); ssFloat << outputPrefix << "_float_lambda_" << lambdas[lambdaId] << ".mha"; Helpers::WriteImage<FloatVectorImageType>(inpainting.GetCurrentOutputImage(), ssFloat.str()); std::stringstream ssRGB; ssRGB.setf(ios::showpoint); ssRGB << outputPrefix << "_RGB_lambda_" << lambdas[lambdaId] << ".mha"; Helpers::WriteVectorImageAsRGB(inpainting.GetCurrentOutputImage(), ssRGB.str()); //Helpers::WriteVectorImageAsRGB(inpainting.GetCurrentOutputImage(), Helpers::ReplaceFileExtension(ss.str(), "png")); } fout.close(); return EXIT_SUCCESS; }
int main(int, char*[]) { // typedef itk::Image<itk::CovariantVector<int, 3>, 2> ImageType; typedef itk::Image<itk::CovariantVector<unsigned char, 3>, 2> ImageType; ImageType::PixelType red; red.Fill(0); red[0] = 255; ImageType::PixelType black; black.Fill(0); ImageType::PixelType white; white.Fill(255); ImageType::PixelType green; // Note this is not 255 because then the magnitude of red and green would be the same, // which makes debugging hard since the gradient of the magnitude image is used internally (in IntroducedEnergy). green.Fill(0); green[1] = 122; ImageType::PixelType blue; blue.Fill(0); blue[2] = 255; ImageType::Pointer image = ImageType::New(); itk::Index<2> imageCorner = {{0,0}}; itk::Size<2> imageSize = {{100,100}}; itk::ImageRegion<2> region(imageCorner,imageSize); image->SetRegions(region); image->Allocate(); Mask::Pointer mask = Mask::New(); mask->SetRegions(region); mask->Allocate(); itk::ImageRegionIteratorWithIndex<Mask> initializeMaskIterator(mask, mask->GetLargestPossibleRegion()); while(!initializeMaskIterator.IsAtEnd()) { if(initializeMaskIterator.GetIndex()[0] < 55) { initializeMaskIterator.Set(mask->GetHoleValue()); } else { initializeMaskIterator.Set(mask->GetValidValue()); } ++initializeMaskIterator; } ITKHelpers::WriteImage(mask.GetPointer(), "mask.png"); // Create a red image itk::ImageRegionIterator<ImageType> initializeIterator(image, image->GetLargestPossibleRegion()); while(!initializeIterator.IsAtEnd()) { initializeIterator.Set(red); ++initializeIterator; } // Setup source and target patch itk::Size<2> patchSize = {{10,10}}; itk::Index<2> sourceCorner = {{10,10}}; itk::ImageRegion<2> sourceRegion(sourceCorner, patchSize); itk::Index<2> targetCorner = {{50,50}}; itk::ImageRegion<2> targetRegion(targetCorner, patchSize); itk::Index<2> perfectSourceCorner = {{75,75}}; itk::ImageRegion<2> perfectSourceRegion(perfectSourceCorner, patchSize); // Make the source patch green itk::ImageRegionIterator<ImageType> sourceRegionIterator(image, sourceRegion); while(!sourceRegionIterator.IsAtEnd()) { sourceRegionIterator.Set(green); ++sourceRegionIterator; } ITKHelpers::WriteImage(image.GetPointer(), "image.png"); { ImageType::Pointer regionHighlightImage = ImageType::New(); ITKHelpers::DeepCopy(image.GetPointer(), regionHighlightImage.GetPointer()); ITKHelpers::OutlineRegion(regionHighlightImage.GetPointer(), sourceRegion, white); ITKHelpers::OutlineRegion(regionHighlightImage.GetPointer(), targetRegion, black); ITKHelpers::OutlineRegion(regionHighlightImage.GetPointer(), perfectSourceRegion, blue); ITKHelpers::WriteImage(regionHighlightImage.GetPointer(), "regions.png"); } IntroducedEnergy<ImageType> introducedEnergy; introducedEnergy.SetDebugImages(true); // Bad match { std::cout << "Bad match:" << std::endl; float patchBoundaryEnergy = introducedEnergy.ComputeIntroducedEnergyPatchBoundary(image, mask, sourceRegion, targetRegion); std::cout << "patchBoundaryEnergy: " << patchBoundaryEnergy << std::endl; float maskBoundaryEnergy = introducedEnergy.ComputeIntroducedEnergyMaskBoundary(image, mask, sourceRegion, targetRegion); std::cout << "maskBoundaryEnergy: " << maskBoundaryEnergy << std::endl; float totalEnergy = introducedEnergy.ComputeIntroducedEnergy(image, mask, sourceRegion, targetRegion); std::cout << "totalEnergy: " << totalEnergy << std::endl; } // Perfect match { std::cout << "Perfect match:" << std::endl; // IntroducedEnergy<ImageType> introducedEnergy; typedef IntroducedEnergy<ImageType> IntroducedEnergyType; float patchBoundaryEnergy = introducedEnergy.ComputeIntroducedEnergyPatchBoundary(image, mask, perfectSourceRegion, targetRegion); std::cout << "patchBoundaryEnergy: " << patchBoundaryEnergy << std::endl; float maskBoundaryEnergy = introducedEnergy.ComputeIntroducedEnergyMaskBoundary(image, mask, perfectSourceRegion, targetRegion); std::cout << "maskBoundaryEnergy: " << maskBoundaryEnergy << std::endl; float totalEnergy = introducedEnergy.ComputeIntroducedEnergy(image, mask, perfectSourceRegion, targetRegion); std::cout << "totalEnergy: " << totalEnergy << std::endl; } return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { unsigned int t = time(NULL); srand(t); itk::Size<2> size; size.Fill(100); itk::Index<2> index; index.Fill(0); itk::ImageRegion<2> region(index, size); /* // Generate a random image (this method doesn't work with VectorImage) itk::RandomImageSource<FloatVectorImageType>::Pointer imageSource = itk::RandomImageSource<FloatVectorImageType>::New(); imageSource->SetNumberOfThreads(1); // to produce non-random results imageSource->SetSize(size); imageSource->SetMin(0); imageSource->SetMax(100); imageSource->Update(); FloatVectorImageType::Pointer image = imageSource->GetOutput(); */ // Generate a random image FloatVectorImageType::Pointer image = FloatVectorImageType::New(); image->SetRegions(region); image->SetNumberOfComponentsPerPixel(3); image->Allocate(); { itk::ImageRegionIterator<FloatVectorImageType> imageIterator(image, image->GetLargestPossibleRegion()); while(!imageIterator.IsAtEnd()) { FloatVectorImageType::PixelType pixel; pixel.SetSize(3); pixel[0] = drand48(); pixel[1] = drand48(); pixel[2] = drand48(); imageIterator.Set(pixel); ++imageIterator; } } // Generate a random membership image IntImageType::Pointer membershipImage = IntImageType::New(); membershipImage->SetRegions(region); membershipImage->Allocate(); membershipImage->FillBuffer(0); { itk::ImageRegionIterator<IntImageType> membershipImageIterator(membershipImage, membershipImage->GetLargestPossibleRegion()); while(!membershipImageIterator.IsAtEnd()) { IntImageType::PixelType pixel; pixel = rand() / 1000; membershipImageIterator.Set(pixel); ++membershipImageIterator; } } // Write the image itk::ImageFileWriter<FloatVectorImageType>::Pointer imageWriter = itk::ImageFileWriter<FloatVectorImageType>::New(); imageWriter->SetFileName("image.mha"); imageWriter->SetInput(image); imageWriter->Update(); // // Generate a random mask // itk::RandomImageSource<Mask>::Pointer maskSource = itk::RandomImageSource<Mask>::New(); // maskSource->SetNumberOfThreads(1); // to produce non-random results // maskSource->SetSize(size); // maskSource->SetMin(0); // maskSource->SetMax(255); // maskSource->Update(); // // // Threshold the mask // //typedef itk::ThresholdImageFilter <UnsignedCharImageType> ThresholdImageFilterType; // typedef itk::BinaryThresholdImageFilter <Mask, Mask> ThresholdImageFilterType; // ThresholdImageFilterType::Pointer thresholdFilter = ThresholdImageFilterType::New(); // thresholdFilter->SetInput(maskSource->GetOutput()); // thresholdFilter->SetLowerThreshold(0); // thresholdFilter->SetUpperThreshold(122); // thresholdFilter->SetOutsideValue(1); // thresholdFilter->SetInsideValue(0); // thresholdFilter->Update(); // Mask::Pointer mask = thresholdFilter->GetOutput(); std::cout << "Creating mask..." << std::endl; Mask::Pointer mask = Mask::New(); mask->SetRegions(region); mask->Allocate(); { itk::ImageRegionIterator<Mask> maskIterator(mask, mask->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { int randomNumber = rand()%10; //std::cout << "randomNumber: " << randomNumber << std::endl; if(randomNumber > 5) { maskIterator.Set(mask->GetHoleValue()); } else { maskIterator.Set(mask->GetValidValue()); } ++maskIterator; } } std::cout << "Writing mask..." << std::endl; // Write the mask itk::ImageFileWriter<Mask>::Pointer maskWriter = itk::ImageFileWriter<Mask>::New(); maskWriter->SetFileName("mask.png"); maskWriter->SetInput(mask); maskWriter->Update(); std::cout << "Creating source patches..." << std::endl; unsigned int patchRadius = 10; // Create source patches itk::ImageRegionConstIterator<FloatVectorImageType> imageIterator(image, image->GetLargestPossibleRegion()); std::vector<Patch> sourcePatches; while(!imageIterator.IsAtEnd()) { itk::Index<2> currentPixel = imageIterator.GetIndex(); itk::ImageRegion<2> region = Helpers::GetRegionInRadiusAroundPixel(currentPixel, patchRadius); if(image->GetLargestPossibleRegion().IsInside(region)) { sourcePatches.push_back(Patch(region)); } ++imageIterator; } std::cout << "Source patches: " << sourcePatches.size() << std::endl; itk::Size<2> targetSize; targetSize.Fill(patchRadius * 2 + 1); itk::Index<2> targetIndex; targetIndex.Fill(3); itk::ImageRegion<2> targetRegion(targetIndex, targetSize); Patch targetPatch(targetRegion); CandidatePairs pairs(targetPatch); pairs.AddPairFromPatch(targetPatch); itk::ImageRegion<2> adjacentRegion = targetRegion; itk::Index<2> adjacentIndex; adjacentIndex[0] = targetIndex[0] + 1; adjacentIndex[1] = targetIndex[1] + 1; adjacentRegion.SetIndex(adjacentIndex); Patch adjacentPatch(adjacentRegion); pairs.AddPairFromPatch(adjacentPatch); //pairs.AddPairFromPatch(sourcePatches[0]); SelfPatchCompare patchCompare; patchCompare.SetPairs(&pairs); patchCompare.SetImage(image); patchCompare.SetMask(mask); patchCompare.SetNumberOfComponentsPerPixel(3); patchCompare.SetMembershipImage(membershipImage); patchCompare.FunctionsToCompute.push_back(boost::bind(&SelfPatchCompare::SetPatchMembershipDifference,&patchCompare,_1)); patchCompare.ComputeAllSourceDifferences(); std::cout << "pairs: " << pairs.size() << std::endl; for(unsigned int i = 0; i < pairs.size(); ++i) { std::cout << "MembershipDifference: " << pairs[i].DifferenceMap[PatchPair::MembershipDifference] << std::endl; } //unsigned int bestMatchSourcePatchId = patchCompare.FindBestPatch(); //std::cout << "bestMatchSourcePatchId: " << bestMatchSourcePatchId << std::endl; /* unsigned int patchId = 1; float slowPatchDifference = patchCompare.SlowDifference(sourcePatches[patchId]); std::cout << "slowPatchDifference: " << slowPatchDifference << std::endl; float fastPatchDifference = patchCompare.PatchDifference(sourcePatches[patchId]); std::cout << "fastPatchDifference: " << fastPatchDifference << std::endl; unsigned int iterations = 1e6; itk::TimeProbe slowTimer; slowTimer.Start(); for(unsigned int i = 0; i < iterations; ++i) { float slowPatchDifference = patchCompare.SlowDifference(sourcePatches[patchId]); } slowTimer.Stop(); std::cout << "Slow Total: " << slowTimer.GetTotal() << std::endl; itk::TimeProbe fastTimer; fastTimer.Start(); for(unsigned int i = 0; i < iterations; ++i) { float fastPatchDifference = patchCompare.PatchDifference(sourcePatches[patchId]); } fastTimer.Stop(); std::cout << "Fast Total: " << fastTimer.GetTotal() << std::endl;*/ return EXIT_SUCCESS; }
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; } };