void Mask::ApplyToRGBImage(TImage* const image, const TColor& color) const { // Using generics, we allow any Color class that has .red(), .green(), and .blue() member functions // to be used to specify the color. if(image->GetLargestPossibleRegion() != this->GetLargestPossibleRegion()) { std::cerr << "Image and mask must be the same size!" << std::endl << "Image region: " << image->GetLargestPossibleRegion() << std::endl << "Mask region: " << this->GetLargestPossibleRegion() << std::endl; return; } // Color the hole pixels in the image. typename TImage::PixelType holeValue; holeValue.SetSize(image->GetNumberOfComponentsPerPixel()); holeValue.Fill(0); if(image->GetNumberOfComponentsPerPixel() >= 3) { holeValue[0] = color.red(); holeValue[1] = color.green(); holeValue[2] = color.blue(); } itk::ImageRegionConstIterator<Mask> maskIterator(this, this->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { if(this->IsHole(maskIterator.GetIndex())) { image->SetPixel(maskIterator.GetIndex(), holeValue); } ++maskIterator; } }
void CriminisiInpainting::InitializeImage() { // Initialize to the input Helpers::DeepCopyVectorImage<FloatVectorImageType>(this->OriginalImage, this->CurrentImage); // We set hole pixels to green so we can visually ensure these pixels are not being copied during the inpainting FloatVectorImageType::PixelType green; green.SetSize(this->OriginalImage->GetNumberOfComponentsPerPixel()); green.Fill(0); green[1] = 255; itk::ImageRegionConstIterator<Mask> maskIterator(this->CurrentMask, this->CurrentMask->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { if(this->CurrentMask->IsHole(maskIterator.GetIndex())) { this->CurrentImage->SetPixel(maskIterator.GetIndex(), green); } ++maskIterator; } #if defined(INTERACTIVE) emit RefreshSignal(); #endif }
void Mask::ApplyRegionToImageRegion(const itk::ImageRegion<2>& maskRegion, TImage* const image, const itk::ImageRegion<2>& imageRegion, const typename TImage::PixelType& color) const { if(maskRegion.GetSize() != imageRegion.GetSize()) { std::cerr << "imageRegion and maskRegion must be the same size!" << std::endl << "Image region: " << imageRegion << std::endl << "Mask region: " << maskRegion << std::endl; return; } itk::ImageRegionConstIterator<Mask> maskIterator(this, maskRegion); itk::ImageRegionIterator<TImage> imageIterator(image, imageRegion); while(!maskIterator.IsAtEnd()) { if(this->IsHole(maskIterator.GetIndex())) { imageIterator.Set(color); } ++maskIterator; ++imageIterator; } }
std::vector<float> ClusterColors::HistogramRegion(const IntImageType* image, const itk::ImageRegion<2>& imageRegion, const Mask* mask, const itk::ImageRegion<2>& maskRegion, const bool invertMask) { EnterFunction("ClusterColors::HistogramRegion(IntImageType)"); std::vector<float> histogram(this->Colors.size(), 0.0f); //std::cout << "histogram.size() " << histogram.size() << std::endl; itk::ImageRegionConstIterator<IntImageType> imageIterator(image, imageRegion); itk::ImageRegionConstIterator<Mask> maskIterator(mask, maskRegion); while(!imageIterator.IsAtEnd()) { if(!(invertMask) * mask->IsHole(maskIterator.GetIndex())) { ++imageIterator; ++maskIterator; continue; } //std::cout << "Attempting to increment bin " << imageIterator.Get() << std::endl; histogram[imageIterator.Get()] += 1.0f; ++imageIterator; ++maskIterator; } LeaveFunction("ClusterColors::HistogramRegion(IntImageType)"); return histogram; }
std::vector<float> ClusterColors::HistogramRegion(const FloatVectorImageType* image, const itk::ImageRegion<2>& imageRegion, const Mask* mask, const itk::ImageRegion<2>& maskRegion, const bool invertMask) { std::vector<float> histogram(this->Colors.size(), 0.0f); itk::ImageRegionConstIterator<FloatVectorImageType> imageIterator(image, imageRegion); itk::ImageRegionConstIterator<Mask> maskIterator(mask, maskRegion); while(!imageIterator.IsAtEnd()) { if(!(invertMask) * mask->IsHole(maskIterator.GetIndex())) { ++imageIterator; ++maskIterator; continue; } FloatVectorImageType::PixelType pixel = imageIterator.Get(); ColorMeasurementVectorType measurement; measurement[0] = pixel[0]; measurement[1] = pixel[1]; measurement[2] = pixel[2]; TreeType::InstanceIdentifierVectorType neighbors; this->KDTree->Search( measurement, 1u, neighbors ); histogram[neighbors[0]] += 1.0f; ++imageIterator; ++maskIterator; } return histogram; }
bool CriminisiInpainting::HasMoreToInpaint() { try { if(this->DebugImages) { Helpers::WriteImage<Mask>(this->CurrentMask, "Debug/HasMoreToInpaint.input.png"); } itk::ImageRegionIterator<Mask> maskIterator(this->CurrentMask, this->CurrentMask->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { // if(this->Debug) // { // std::cout << "HasMoreToInpaint - mask pixel: " << static_cast<unsigned int>(maskIterator.Get()) << std::endl; // } if(this->CurrentMask->IsHole(maskIterator.GetIndex())) { return true; } ++maskIterator; } // If no pixels were holes, then we don't have any more to inpaint. return false; } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught in HasMoreToInpaint!" << std::endl; std::cerr << err << std::endl; exit(-1); } }
void StrokeMask:: Write(const std::string& filename, const TPixel& strokeValue) { typedef itk::Image<TPixel, 2> ImageType; typename ImageType::Pointer image = ImageType::New(); image->SetRegions(this->GetLargestPossibleRegion()); image->Allocate(); itk::ImageRegionConstIteratorWithIndex<StrokeMask> maskIterator(this, this->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { if(maskIterator.Get() == StrokeMaskPixelTypeEnum::STROKE) { image->SetPixel(maskIterator.GetIndex(), strokeValue); } else { image->SetPixel(maskIterator.GetIndex(), itk::NumericTraits<TPixel>::Zero); } ++maskIterator; } typedef itk::ImageFileWriter<ImageType> WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName(filename); writer->SetInput(image); writer->Update(); }
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); }
float SelfPatchCompare::SlowAverageSquaredDifference(const itk::ImageRegion<2>& sourceRegion) { // This function assumes that all pixels in the source region are unmasked. // This method uses 3 iterators - one for the mask, and one for each image patch. // The entire mask is traversed looking for valid pixels, and then comparing the image pixels. // This is very inefficient because, since the target region stays constant for many thousands of patch // comparisons, the mask need only be traversed once. This method is performed by ComputeOffsets() // and PatchDifference*(). This function is only here for comparison purposes (to ensure the result of the other functions // is correct). itk::ImageRegionConstIterator<FloatVectorImageType> sourcePatchIterator(this->Image, sourceRegion); itk::ImageRegionConstIterator<FloatVectorImageType> targetPatchIterator(this->Image, this->TargetRegion); itk::ImageRegionConstIterator<Mask> maskIterator(this->MaskImage, this->TargetRegion); float sumSquaredDifferences = 0; this->NumberOfPixelsCompared = 0; float squaredDifference = 0; while(!sourcePatchIterator.IsAtEnd()) { itk::Index<2> currentPixel = maskIterator.GetIndex(); if(this->MaskImage->IsValid(currentPixel)) { //std::cout << "Offset from iterator: " << this->Image->ComputeOffset(maskIterator.GetIndex()) * componentsPerPixel; FloatVectorImageType::PixelType sourcePixel = sourcePatchIterator.Get(); FloatVectorImageType::PixelType targetPixel = targetPatchIterator.Get(); squaredDifference = PixelSquaredDifference(sourcePixel, targetPixel); //std::cout << "Source pixel: " << sourcePixel << " target pixel: " << targetPixel << "Difference: " << difference << " squaredDifference: " << squaredDifference << std::endl; sumSquaredDifferences += squaredDifference; this->NumberOfPixelsCompared++; } ++sourcePatchIterator; ++targetPatchIterator; ++maskIterator; } // end while iterate over sourcePatch float averageSquaredDifferences = sumSquaredDifferences / static_cast<float>(this->NumberOfPixelsCompared); return averageSquaredDifferences; }
inline void SimpleInitializerFromMask(Mask* const maskImage, TVisitor* const visitor, TGraph& g) { std::cout << "SimpleInitializer" << std::endl; itk::ImageRegionConstIteratorWithIndex<Mask> maskIterator(maskImage, maskImage->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { typename boost::graph_traits<TGraph>::vertex_descriptor node; node[0] = maskIterator.GetIndex()[0]; node[1] = maskIterator.GetIndex()[1]; //std::cout << "Initializing " << maskIterator.GetIndex() << std::endl; visitor->initialize_vertex(node, g); ++maskIterator; } }
bool Mask::IsValid(const itk::ImageRegion<2>& region) const { // If any of the pixels in the region are invalid, the region is invalid. itk::ImageRegionConstIterator<Mask> maskIterator(this, region); while(!maskIterator.IsAtEnd()) { if(!this->IsValid(maskIterator.GetIndex())) { //std::cout << "Mask::IsValid - Pixel " << maskIterator.GetIndex() << " has value " << static_cast<unsigned int>(maskIterator.Get()) // << " which makes the region invalid because Mask::ValidValue = " << static_cast<unsigned int>(this->ValidValue) << std::endl; return false; } ++maskIterator; } return true; }
float CriminisiInpainting::ComputeConfidenceTerm(const itk::Index<2>& queryPixel) { //DebugMessage<itk::Index<2>>("Computing confidence for ", queryPixel); try { // Allow for regions on/near the image border itk::ImageRegion<2> region = this->CurrentMask->GetLargestPossibleRegion(); region.Crop(Helpers::GetRegionInRadiusAroundPixel(queryPixel, this->PatchRadius[0])); itk::ImageRegionConstIterator<Mask> maskIterator(this->CurrentMask, region); itk::ImageRegionConstIterator<FloatScalarImageType> confidenceIterator(this->ConfidenceImage, region); maskIterator.GoToBegin(); confidenceIterator.GoToBegin(); // The confidence is computed as the sum of the confidences of patch pixels in the source region / area of the patch float sum = 0; while(!maskIterator.IsAtEnd()) { if(this->CurrentMask->IsValid(maskIterator.GetIndex())) { sum += confidenceIterator.Get(); } ++confidenceIterator; ++maskIterator; } unsigned int numberOfPixels = GetNumberOfPixelsInPatch(); float areaOfPatch = static_cast<float>(numberOfPixels); float confidence = sum/areaOfPatch; DebugMessage<float>("Confidence: ", confidence); return confidence; } catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught in ComputeConfidenceTerm!" << std::endl; std::cerr << err << std::endl; exit(-1); } }
itk::ImageRegion<2> Mask::FindFirstValidPatch(const unsigned int patchRadius) { itk::ImageRegionConstIteratorWithIndex<Mask> maskIterator(this, this->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { itk::ImageRegion<2> region = GetRegionInRadiusAroundPixel(maskIterator.GetIndex(), patchRadius); if(this->IsValid(region)) { return region; } ++maskIterator; } throw std::runtime_error("No valid patches found!"); }
void Mask::Invert() { // Exchange HoleValue and ValidValue, but leave everything else alone. itk::ImageRegionIterator<Mask> maskIterator(this, this->GetLargestPossibleRegion()); unsigned int invertedCounter = 0; while(!maskIterator.IsAtEnd()) { if(this->IsValid(maskIterator.GetIndex())) { maskIterator.Set(this->HoleValue); invertedCounter++; } else if(this->IsHole(maskIterator.GetIndex())) { maskIterator.Set(this->ValidValue); invertedCounter++; } ++maskIterator; } //std::cout << "Inverted " << invertedCounter << " in the mask." << std::endl; }
ValidRegionIterator::ValidRegionIterator(const Mask* const mask, const itk::ImageRegion<2>& region, const unsigned int patchRadius): MaskImage(mask), PatchRadius(patchRadius) { itk::ImageRegionConstIterator<Mask> maskIterator(mask, region); // Create all of the valid regions and store them in a vector while(!maskIterator.IsAtEnd()) { itk::Index<2> currentPixel = maskIterator.GetIndex(); itk::ImageRegion<2> currentPatchRegion = ITKHelpers::GetRegionInRadiusAroundPixel(currentPixel, this->PatchRadius); if(this->MaskImage->GetLargestPossibleRegion().IsInside(currentPatchRegion)) { if(this->MaskImage->IsValid(currentPatchRegion)) { this->ValidRegions.push_back(currentPatchRegion); } } ++maskIterator; } }
void Mask::ApplyToScalarImage(TImage* const image, typename TImage::PixelType holeValue) const { if(image->GetLargestPossibleRegion() != this->GetLargestPossibleRegion()) { std::cerr << "Image and mask must be the same size!" << std::endl << "Image region: " << image->GetLargestPossibleRegion() << std::endl << "Mask region: " << this->GetLargestPossibleRegion() << std::endl; return; } itk::ImageRegionConstIterator<Mask> maskIterator(this, this->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { if(this->IsHole(maskIterator.GetIndex())) { image->SetPixel(maskIterator.GetIndex(), holeValue); } ++maskIterator; } }
/** Find hole pixels that are touching valid pixels.*/ std::vector<itk::Index<2> > Mask::FindBoundaryPixelsInRegion(const itk::ImageRegion<2>& region, const Mask::PixelType& whichSideOfBoundary) const { std::vector<itk::Index<2> > boundaryPixels; itk::ImageRegionConstIteratorWithIndex<Mask> maskIterator(this, region); while(!maskIterator.IsAtEnd()) { if(maskIterator.Get() == whichSideOfBoundary) { if(HasNeighborWithValueOtherThan(maskIterator.GetIndex(), this, whichSideOfBoundary)) { boundaryPixels.push_back(maskIterator.GetIndex()); } } ++maskIterator; } return boundaryPixels; }
unsigned int Mask::CountValidPatches(const unsigned int patchRadius) const { itk::ImageRegionConstIteratorWithIndex<Mask> maskIterator(this, this->GetLargestPossibleRegion()); unsigned int counter = 0; // std::cout << "CountValidPatches (patch radius " << patchRadius << ")..." << std::endl; while(!maskIterator.IsAtEnd()) { itk::ImageRegion<2> region = GetRegionInRadiusAroundPixel(maskIterator.GetIndex(), patchRadius); if(this->IsValid(region)) { counter++; } ++maskIterator; } //std::cout << "There were " << counter << " valid patches." << std::endl; return counter; }
ImagePatchVectorizedIndices<TImage>::ImagePatchVectorizedIndices(TImage* const image, Mask* const maskImage, const itk::ImageRegion<2>& region) : Region(region), Image(image), MaskImage(maskImage), InsideImage(false) { if(image->GetLargestPossibleRegion().IsInside(region)) { this->InsideImage = true; } else { this->FullyValid = false; return; } this->FullyValid = maskImage->IsValid(region); this->FullyValid = true; itk::ImageRegionConstIteratorWithIndex<Mask> maskIterator(maskImage, region); while(!maskIterator.IsAtEnd()) { if(maskImage->IsHole(maskIterator.GetIndex())) { this->FullyValid = false; break; } ++maskIterator; } if(this->FullyValid) { this->SetStatus(SOURCE_NODE); CreateIndexVector(); } else { this->SetStatus(INVALID); } }
void Mask::Cleanup() { // We want to interpret pixels that are "pretty much hole value" as holes, and pixels that // are "pretty much valid value" as valid. The "do not use" pixels must be very far away from both of these values. itk::ImageRegionIterator<Mask> maskIterator(this, this->GetLargestPossibleRegion()); float tolerance = 4; while(!maskIterator.IsAtEnd()) { if(fabs(maskIterator.Get() - this->ValidValue) < tolerance) { //std::cout << "Setting valid pixel to " << static_cast<unsigned int>(this->ValidValue) << std::endl; maskIterator.Set(this->ValidValue); } else if(fabs(maskIterator.Get() - this->HoleValue) < tolerance) { //std::cout << "Setting hole pixel to " << static_cast<unsigned int>(this->HoleValue) << std::endl; maskIterator.Set(this->HoleValue); } ++maskIterator; } }
void CriminisiInpainting::UpdateConfidences(const itk::ImageRegion<2>& inputRegion) { try { // Force the region to update to be entirely inside the image itk::ImageRegion<2> region = CropToValidRegion(inputRegion); // Use an iterator to find masked pixels. Compute their new value, and save it in a vector of pixels and their new values. // Do not update the pixels until after all new values have been computed, because we want to use the old values in all of // the computations. itk::ImageRegionConstIterator<Mask> maskIterator(this->CurrentMask, region); std::vector<UpdatePixel> pixelsToUpdate; while(!maskIterator.IsAtEnd()) { if(this->CurrentMask->IsHole(maskIterator.GetIndex())) { itk::Index<2> currentPixel = maskIterator.GetIndex(); pixelsToUpdate.push_back(UpdatePixel(currentPixel, ComputeConfidenceTerm(currentPixel))); } ++maskIterator; } // end while looop with iterator // Actually update the pixels for(unsigned int i = 0; i < pixelsToUpdate.size(); ++i) { this->ConfidenceImage->SetPixel(pixelsToUpdate[i].index, pixelsToUpdate[i].value); } } // end try catch( itk::ExceptionObject & err ) { std::cerr << "ExceptionObject caught in UpdateConfidences!" << std::endl; std::cerr << err << std::endl; exit(-1); } }
void ForegroundBackgroundSegmentMask:: Write(const std::string& filename, const ForegroundPixelValueWrapper<TPixel>& foregroundValue, const BackgroundPixelValueWrapper<TPixel>& backgroundValue) { typedef itk::Image<TPixel, 2> ImageType; typename ImageType::Pointer image = ImageType::New(); image->SetRegions(this->GetLargestPossibleRegion()); image->Allocate(); itk::ImageRegionConstIteratorWithIndex<ForegroundBackgroundSegmentMask> maskIterator(this, this->GetLargestPossibleRegion()); while(!maskIterator.IsAtEnd()) { if(maskIterator.Get() == ForegroundBackgroundSegmentMaskPixelTypeEnum::FOREGROUND) { image->SetPixel(maskIterator.GetIndex(), foregroundValue.Value); } else if(maskIterator.Get() == ForegroundBackgroundSegmentMaskPixelTypeEnum::BACKGROUND) { image->SetPixel(maskIterator.GetIndex(), backgroundValue.Value); } ++maskIterator; } typedef itk::ImageFileWriter<ImageType> WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->SetFileName(filename); writer->SetInput(image); writer->Update(); }
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; }
void ManualPatchSelectionDialog<TImage>::slot_UpdateResult(const itk::ImageRegion<2>& sourceRegion, const itk::ImageRegion<2>& targetRegion) { assert(sourceRegion.GetSize() == targetRegion.GetSize()); if(!this->Image->GetLargestPossibleRegion().IsInside(sourceRegion)) { std::cerr << "Source region is outside the image!" << std::endl; return; } QImage qimage(sourceRegion.GetSize()[0], sourceRegion.GetSize()[1], QImage::Format_RGB888); if(MaskImage->CountHolePixels(sourceRegion) > 0) { //std::cerr << "The source patch must not have any hole pixels!" << std::endl; //btnAccept->setVisible(false); qimage.fill(Qt::green); } else { typename TImage::Pointer tempImage = TImage::New(); ITKHelpers::ConvertTo3Channel(this->Image, tempImage.GetPointer()); if(this->Image->GetNumberOfComponentsPerPixel() != 3) { ITKHelpers::ScaleAllChannelsTo255(tempImage.GetPointer()); } itk::ImageRegionIterator<TImage> sourceIterator(tempImage, sourceRegion); itk::ImageRegionIterator<TImage> targetIterator(tempImage, targetRegion); itk::ImageRegionIterator<Mask> maskIterator(MaskImage, targetRegion); typename TImage::Pointer resultPatch = TImage::New(); resultPatch->SetNumberOfComponentsPerPixel(Image->GetNumberOfComponentsPerPixel()); itk::ImageRegion<2> resultPatchRegion; resultPatchRegion.SetSize(sourceRegion.GetSize()); resultPatch->SetRegions(resultPatchRegion); resultPatch->Allocate(); while(!maskIterator.IsAtEnd()) { ITKHelpers::FloatVectorImageType::PixelType pixel; if(MaskImage->IsHole(maskIterator.GetIndex())) { pixel = sourceIterator.Get(); } else { pixel = targetIterator.Get(); } itk::Offset<2> offset = sourceIterator.GetIndex() - sourceRegion.GetIndex(); itk::Index<2> offsetIndex; offsetIndex[0] = offset[0]; offsetIndex[1] = offset[1]; resultPatch->SetPixel(offsetIndex, pixel); ++sourceIterator; ++targetIterator; ++maskIterator; } // end iterator loop qimage = ITKQtHelpers::GetQImageColor(resultPatch.GetPointer(), resultPatch->GetLargestPossibleRegion()); } // end else this->ResultPatchScene->clear(); QGraphicsPixmapItem* item = this->ResultPatchScene->addPixmap(QPixmap::fromImage(qimage)); gfxResult->fitInView(item); }