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; } }
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); }
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; }
void Vector() { typedef itk::Image<unsigned char, 2 > ChannelType; const unsigned int NumberOfChannels = 3; typedef itk::Image<itk::CovariantVector<unsigned char, NumberOfChannels>, 2 > ImageType; ImageType::Pointer image = ImageType::New(); itk::Index<2> corner = {{0,0}}; itk::Size<2> imageSize = {{500,500}}; itk::ImageRegion<2> fullRegion(corner, imageSize); image->SetRegions(fullRegion); image->Allocate(); for(unsigned int i = 0; i < NumberOfChannels; ++i) { itk::RandomImageSource<ChannelType>::Pointer randomImageSource = itk::RandomImageSource<ChannelType>::New(); randomImageSource->SetNumberOfThreads(1); // to produce non-random results randomImageSource->SetSize(imageSize); randomImageSource->Update(); ITKHelpers::SetChannel(image.GetPointer(), i, randomImageSource->GetOutput()); } itk::Size<2> patchSize = {{21,21}}; // There is nothing magic about these particular patches itk::Index<2> targetCorner = {{319, 302}}; itk::ImageRegion<2> targetRegion(targetCorner, patchSize); itk::Index<2> sourceCorner = {{341, 300}}; itk::ImageRegion<2> sourceRegion(sourceCorner, patchSize); Mask::Pointer mask = Mask::New(); mask->SetRegions(fullRegion); mask->Allocate(); ITKHelpers::SetImageToConstant(mask.GetPointer(), mask->GetValidValue()); typedef SumSquaredPixelDifference<ImageType::PixelType> PixelDifferenceType; typedef ImagePatchPixelDescriptor<ImageType> PatchType; ImagePatchDifference<PatchType, PixelDifferenceType> imagePatchDifference; PatchType targetPatch(image, mask, targetRegion); PatchType sourcePatch(image, mask, sourceRegion); float difference = imagePatchDifference(targetPatch, sourcePatch); std::cout << "GMHDifference: " << difference << std::endl; }
void Scalar() { typedef itk::Image< unsigned char, 2 > ImageType; itk::Size<2> imageSize = {{500,500}}; itk::RandomImageSource<ImageType>::Pointer randomImageSource = itk::RandomImageSource<ImageType>::New(); randomImageSource->SetNumberOfThreads(1); // to produce non-random results randomImageSource->SetSize(imageSize); randomImageSource->Update(); ImageType* image = randomImageSource->GetOutput(); itk::Size<2> patchSize = {{21,21}}; // There is nothing magic about these particular patches itk::Index<2> targetCorner = {{319, 302}}; itk::ImageRegion<2> targetRegion(targetCorner, patchSize); itk::Index<2> sourceCorner = {{341, 300}}; itk::ImageRegion<2> sourceRegion(sourceCorner, patchSize); Mask::Pointer mask = Mask::New(); mask->SetRegions(randomImageSource->GetOutput()->GetLargestPossibleRegion()); mask->Allocate(); ITKHelpers::SetImageToConstant(mask.GetPointer(), mask->GetValidValue()); typedef SumSquaredPixelDifference<ImageType::PixelType> PixelDifferenceType; typedef ImagePatchPixelDescriptor<ImageType> PatchType; ImagePatchDifference<PatchType, PixelDifferenceType> imagePatchDifference; PatchType targetPatch(image, mask, targetRegion); PatchType sourcePatch(image, mask, sourceRegion); float difference = imagePatchDifference(targetPatch, sourcePatch); std::cout << "Difference: " << difference << std::endl; }
void LidarSegmentationWidget::on_btnErodeSources_clicked() { Mask::Pointer sourcesImage = Mask::New(); sourcesImage->SetRegions(this->ImageRegion); ITKHelpers::IndicesToBinaryImage(this->Sources, sourcesImage); typedef itk::BinaryBallStructuringElement<Mask::PixelType,2> StructuringElementType; StructuringElementType structuringElementBig; structuringElementBig.SetRadius(3); structuringElementBig.CreateStructuringElement(); typedef itk::BinaryErodeImageFilter<Mask, Mask, StructuringElementType> BinaryErodeImageFilterType; BinaryErodeImageFilterType::Pointer erodeFilter = BinaryErodeImageFilterType::New(); erodeFilter->SetInput(sourcesImage); erodeFilter->SetKernel(structuringElementBig); erodeFilter->Update(); //this->Sources.clear(); this->Sources = ITKHelpers::GetNonZeroPixels(erodeFilter->GetOutput()); UpdateSelections(); }
void TestComputeMaskedImage1DHistogram() { // // Single channel // { // typedef itk::Image<unsigned char, 2> ImageType; // ImageType::Pointer image = ImageType::New(); // ImageType::IndexType corner = {{0,0}}; // ImageType::SizeType size = {{100,100}}; // ImageType::RegionType region(corner, size); // image->SetRegions(region); // image->Allocate(); // itk::ImageRegionIterator<ImageType> imageIterator(image,region); // while(!imageIterator.IsAtEnd()) // { // if(imageIterator.GetIndex()[0] < 70) // { // imageIterator.Set(255); // } // else // { // imageIterator.Set(0); // } // ++imageIterator; // } // ImageType::PixelType rangeMin = 0; // ImageType::PixelType rangeMax = 255; // unsigned int numberOfBins = 10; // typedef int BinValueType; // typedef Histogram<BinValueType>::HistogramType HistogramType; // HistogramType histogram = Histogram<BinValueType>::ComputeImageHistogram1D(image.GetPointer(), // image->GetLargestPossibleRegion(), // numberOfBins, rangeMin, rangeMax); // Histogram<BinValueType>::OutputHistogram(histogram); // std::cout << std::endl; // } // Multi channel VectorImage { typedef itk::VectorImage<unsigned char, 2> ImageType; ImageType::Pointer image = ImageType::New(); ImageType::IndexType corner = {{0,0}}; ImageType::SizeType size = {{100,100}}; ImageType::RegionType region(corner, size); image->SetRegions(region); image->SetNumberOfComponentsPerPixel(3); image->Allocate(); Mask::Pointer mask = Mask::New(); mask->SetRegions(region); mask->Allocate(); itk::ImageRegionIterator<ImageType> imageIterator(image,region); while(!imageIterator.IsAtEnd()) { ImageType::PixelType pixel(image->GetNumberOfComponentsPerPixel()); if(imageIterator.GetIndex()[0] < 70) { for(unsigned int i = 0; i < pixel.GetSize(); ++i) { pixel[i] = 255; } } else { for(unsigned int i = 0; i < pixel.GetSize(); ++i) { pixel[i] = 0; } } imageIterator.Set(pixel); ++imageIterator; } // TypeTraits<ImageType::PixelType>::ComponentType rangeMin = 0; // TypeTraits<ImageType::PixelType>::ComponentType rangeMax = 255; ImageType::PixelType rangeMins; rangeMins.SetSize(image->GetNumberOfComponentsPerPixel()); rangeMins.Fill(0); ImageType::PixelType rangeMaxs; rangeMaxs.SetSize(image->GetNumberOfComponentsPerPixel()); rangeMaxs.Fill(255); unsigned int numberOfBinsPerComponent = 10; typedef int BinValueType; itk::ImageRegion<2> imageRegion = image->GetLargestPossibleRegion(); itk::ImageRegion<2> maskRegion = image->GetLargestPossibleRegion(); typedef MaskedHistogramGenerator<BinValueType> HistogramGeneratorType; typedef HistogramGeneratorType::HistogramType HistogramType; bool allowOutside = false; HistogramType histogram = HistogramGeneratorType::ComputeMaskedImage1DHistogram(image.GetPointer(), imageRegion, mask.GetPointer(), maskRegion, numberOfBinsPerComponent, rangeMins, rangeMaxs, allowOutside, HoleMaskPixelTypeEnum::VALID); histogram.Print(); std::cout << std::endl; } // // Multi channel Image<CovariantVector> // { // typedef itk::Image<itk::CovariantVector<unsigned char, 3>, 2> ImageType; // ImageType::Pointer image = ImageType::New(); // ImageType::IndexType corner = {{0,0}}; // ImageType::SizeType size = {{100,100}}; // ImageType::RegionType region(corner, size); // image->SetRegions(region); // image->Allocate(); // itk::ImageRegionIterator<ImageType> imageIterator(image,region); // while(!imageIterator.IsAtEnd()) // { // ImageType::PixelType pixel(image->GetNumberOfComponentsPerPixel()); // if(imageIterator.GetIndex()[0] < 70) // { // for(unsigned int i = 0; i < pixel.GetNumberOfComponents(); ++i) // { // pixel[i] = 255; // } // } // else // { // for(unsigned int i = 0; i < pixel.GetNumberOfComponents(); ++i) // { // pixel[i] = 0; // } // } // imageIterator.Set(pixel); // ++imageIterator; // } // TypeTraits<ImageType::PixelType>::ComponentType rangeMin = 0; // TypeTraits<ImageType::PixelType>::ComponentType rangeMax = 255; // unsigned int numberOfBinsPerComponent = 10; // typedef int BinValueType; // Histogram<BinValueType>::HistogramType histogram = Histogram<BinValueType>::ComputeImageHistogram1D(image.GetPointer(), // image->GetLargestPossibleRegion(), // numberOfBinsPerComponent, rangeMin, rangeMax); // Histogram<BinValueType>::OutputHistogram(histogram); // std::cout << std::endl; // } }
int main(int argc, char* argv[]) { // Verify arguments if(argc < 5) { std::cout << "Usage: PatchImage repeatX repeatY outputImage" << std::endl; return EXIT_FAILURE; } // Parse arguments std::string patchImageFilename = argv[1]; std::stringstream ssRepeatX; ssRepeatX << argv[2]; unsigned int repeatX = 0; ssRepeatX >> repeatX; std::stringstream ssRepeatY; ssRepeatY << argv[3]; unsigned int repeatY = 0; ssRepeatY >> repeatY; std::string outputFilename = argv[4]; // Output arguments std::cout << "Patch image: " << patchImageFilename << std::endl << "Repeat X: " << repeatX << std::endl << "Repeat Y: " << repeatY << std::endl << "Output image: " << outputFilename << std::endl; //typedef itk::VectorImage<float, 2> ImageType; typedef itk::Image<itk::CovariantVector<float, 3>, 2> ImageType; // Read patch image typedef itk::ImageFileReader<ImageType> ImageReaderType; ImageReaderType::Pointer patchImageReader = ImageReaderType::New(); patchImageReader->SetFileName(patchImageFilename); patchImageReader->Update(); Mask::Pointer mask = Mask::New(); itk::ImageRegion<2> patchRegion = patchImageReader->GetOutput()->GetLargestPossibleRegion(); mask->SetRegions(patchRegion); mask->Allocate(); itk::Index<2> holeCorner = {{1,1}}; itk::Size<2> holeSize = patchRegion.GetSize(); holeSize[0] -= 2; // Missing one row on the top, and one row on the bottom holeSize[1] -= 2; // Missing one column on the left, and one column on the right itk::ImageRegion<2> holeRegion(holeCorner, holeSize); mask->SetValid(patchRegion); mask->SetHole(holeRegion); ImageType::Pointer seamlessPatch = ImageType::New(); ITKHelpers::DeepCopy(patchImageReader->GetOutput(), seamlessPatch.GetPointer()); // Enforce periodic boundary conditions // Top and bottom for(int i = 0; i < static_cast<int>(patchRegion.GetSize()[1]); ++i) { itk::Index<2> topPixelIndex = {{0, i}}; itk::Index<2> bottomPixelIndex = {{static_cast<int>(patchRegion.GetSize()[0])-1, i}}; ImageType::PixelType topPixelValue = seamlessPatch->GetPixel(topPixelIndex); ImageType::PixelType bottomPixelValue = seamlessPatch->GetPixel(bottomPixelIndex); ImageType::PixelType averageValue = (topPixelValue + bottomPixelValue)/2.0f; seamlessPatch->SetPixel(topPixelIndex, averageValue); seamlessPatch->SetPixel(bottomPixelIndex, averageValue); } // Left and right for(int i = 0; i < static_cast<int>(patchRegion.GetSize()[0]); ++i) { itk::Index<2> leftPixelIndex = {{i, 0}}; itk::Index<2> rightPixelIndex = {{i, static_cast<int>(patchRegion.GetSize()[1])-1}}; ImageType::PixelType leftPixelValue = seamlessPatch->GetPixel(leftPixelIndex); ImageType::PixelType rightPixelValue = seamlessPatch->GetPixel(rightPixelIndex); ImageType::PixelType averageValue = (leftPixelValue + rightPixelValue)/2.0f; seamlessPatch->SetPixel(leftPixelIndex, averageValue); seamlessPatch->SetPixel(rightPixelIndex, averageValue); } typedef PoissonEditingParent::GuidanceFieldType GuidanceFieldType; std::vector<GuidanceFieldType::Pointer> guidanceFields = PoissonEditingParent::ComputeGuidanceField(patchImageReader->GetOutput()); ImageType::Pointer output = ImageType::New(); FillImage(seamlessPatch.GetPointer(), mask.GetPointer(), guidanceFields, output.GetPointer(), patchRegion, seamlessPatch.GetPointer()); // Write output ITKHelpers::WriteRGBImage(output.GetPointer(), outputFilename); // Original tiled ImageType::Pointer originalTiled = ImageType::New(); TilePatch(patchImageReader->GetOutput(), repeatX, repeatY, originalTiled.GetPointer()); ITKHelpers::WriteRGBImage(originalTiled.GetPointer(), "original_tiled.png"); // Seamless tiled ImageType::Pointer seamlessTiled = ImageType::New(); TilePatch(output.GetPointer(), repeatX, repeatY, seamlessTiled.GetPointer()); ITKHelpers::WriteRGBImage(seamlessTiled.GetPointer(), "seamless_tiled.png"); 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; }
int main(int argc, char*argv[]) { if(argc != 6) { std::cerr << "Required arguments: image output R G B" << std::endl; return EXIT_FAILURE; } std::vector<int> values(3,0); std::stringstream ss; unsigned int counter = 0; for(int i = 3; i < argc; ++i) { ss << argv[i] << " "; counter++; } for(int i = 0; i < 3; ++i) { ss >> values[i]; } // itk::RGBPixel<unsigned char> color; // color.SetRed(values[0]); // color.SetGreen(values[1]); // color.SetBlue(values[2]); Color color; color.r = values[0]; color.g = values[1]; color.b = values[2]; std::string imageFilename = argv[1]; std::string outputMaskFilename = argv[2]; std::cout << "Reading image: " << imageFilename << std::endl; std::cout << "outputMaskFilename: " << outputMaskFilename << std::endl; std::cout << "Color: " << static_cast<int>(values[0]) << " " << static_cast<int>(values[1]) << " " << static_cast<int>(values[2]) << std::endl; //typedef itk::Image<float, 2> ImageType; typedef itk::Image<itk::CovariantVector<unsigned char, 3>, 2> ImageType; ImageType::PixelType pixelColor; pixelColor[0] = color.r; pixelColor[1] = color.g; pixelColor[2] = color.b; typedef itk::ImageFileReader<ImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename.c_str()); imageReader->Update(); Mask::Pointer mask = Mask::New(); mask->SetRegions(imageReader->GetOutput()->GetLargestPossibleRegion()); mask->Allocate(); mask->CreateFromImage(imageReader->GetOutput(), pixelColor); OutputHelpers::WriteImage(mask.GetPointer(), outputMaskFilename); return EXIT_SUCCESS; }
void LidarSegmentationWidget::GenerateNeighborSinks() { Mask::Pointer sourcesImage = Mask::New(); sourcesImage->SetRegions(this->ImageRegion); ITKHelpers::IndicesToBinaryImage(this->Sources, sourcesImage); ITKHelpers::WriteImage(sourcesImage.GetPointer(), "sourcesImage.png"); // Dilate the mask std::cout << "Dilating mask..." << std::endl; typedef itk::BinaryBallStructuringElement<Mask::PixelType, 2> StructuringElementType; StructuringElementType structuringElement; structuringElement.SetRadius(1); structuringElement.CreateStructuringElement(); typedef itk::BinaryDilateImageFilter<Mask, Mask, StructuringElementType> BinaryDilateImageFilterType; BinaryDilateImageFilterType::Pointer dilateFilter = BinaryDilateImageFilterType::New(); dilateFilter->SetInput(sourcesImage); dilateFilter->SetKernel(structuringElement); dilateFilter->Update(); // Binary XOR the images to get the difference image //std::cout << "XORing masks..." << std::endl; typedef itk::XorImageFilter<Mask> XorImageFilterType; XorImageFilterType::Pointer xorFilter = XorImageFilterType::New(); xorFilter->SetInput1(dilateFilter->GetOutput()); xorFilter->SetInput2(sourcesImage); xorFilter->Update(); ITKHelpers::WriteImage(xorFilter->GetOutput(), "boundaryOfSegmentation.png"); // Iterate over the border pixels. If the closest pixel in the original segmentation has // a depth greater than a threshold, mark it as a new sink. Else, do not. std::cout << "Determining which boundary pixels should be declared background..." << std::endl; //std::cout << "There should be " << Helpers::CountNonZeroPixels(xorFilter->GetOutput()) // << " considered." << std::endl; typedef std::vector<itk::Index<2> > VectorOfPixelsType; VectorOfPixelsType newSinks; typedef itk::VectorIndexSelectionCastImageFilter<ImageType, FloatScalarImageType> IndexSelectionType; IndexSelectionType::Pointer indexSelectionFilter = IndexSelectionType::New(); indexSelectionFilter->SetIndex(3); indexSelectionFilter->SetInput(this->Image); indexSelectionFilter->Update(); FloatScalarImageType::Pointer depthImage = indexSelectionFilter->GetOutput(); //float sameObjectThreshold = 0.1f; VectorOfPixelsType consideredPixels; itk::ImageRegionIterator<Mask> imageIterator(xorFilter->GetOutput(), xorFilter->GetOutput()->GetLargestPossibleRegion()); while(!imageIterator.IsAtEnd()) { if(imageIterator.Get()) // If the current pixel is in question { consideredPixels.push_back(imageIterator.GetIndex()); } ++imageIterator; } std::cout << "There are " << consideredPixels.size() << " potential new sink pixels." << std::endl; for(VectorOfPixelsType::const_iterator iter = consideredPixels.begin(); iter != consideredPixels.end(); ++iter) { //std::cout << "Considering pixel " << consideredCounter << " (index " // << imageIterator.GetIndex() << ")" << std::endl; ImageType::PixelType currentPixel = this->Image->GetPixel(*iter); unsigned int radius = this->txtBackgroundCheckRadius->text().toUInt(); ImageType::RegionType desiredRegion = ITKHelpers::GetRegionInRadiusAroundPixel(*iter, radius); //std::cout << "desiredRegion: " << desiredRegion << std::endl; itk::ImageRegionIterator<Mask> sourcesImageIterator(sourcesImage, desiredRegion); std::vector<float> nonForegroundDepths; std::vector<float> foregroundDepths; while(!sourcesImageIterator.IsAtEnd()) { if(sourcesImageIterator.Get()) { foregroundDepths.push_back(depthImage->GetPixel(sourcesImageIterator.GetIndex())); } else { nonForegroundDepths.push_back(depthImage->GetPixel(sourcesImageIterator.GetIndex())); } ++sourcesImageIterator; } if(nonForegroundDepths.size() < 1) { } float nonForegroundMedian = Helpers::VectorMedian(nonForegroundDepths); float foregroundMedian = Helpers::VectorMedian(foregroundDepths); float difference = fabs(foregroundMedian - nonForegroundMedian); if(difference > this->txtBackgroundThreshold->text().toFloat()) { //std::cout << "Difference was " << difference << " so this is a sink pixel." << std::endl; newSinks.push_back(*iter); } else { //std::cout << "Difference was " << difference << " so this is NOT a sink pixel." << std::endl; } } // end loop over considered pixels unsigned char blue[3] = {0, 0, 255}; // ImageType::PixelType blue(3); // blue[0] = 0; // blue[1] = 0; // blue[2] = 255; ITKVTKHelpers::SetPixels(this->SourceSinkImageData.GetPointer(), consideredPixels, blue); this->SourceSinkImageData->Modified(); this->Refresh(); // Save the new sink pixels for inspection UnsignedCharScalarImageType::Pointer newSinksImage = UnsignedCharScalarImageType::New(); newSinksImage->SetRegions(this->Image->GetLargestPossibleRegion()); newSinksImage->Allocate(); ITKHelpers::IndicesToBinaryImage(newSinks, newSinksImage); ITKHelpers::WriteImage(newSinksImage.GetPointer(), "newSinks.png"); //std::cout << "Out of " << consideredCounter << " pixels considered, " // << backgroundCounter << " were declared background." << std::endl; // Set the new sinks std::cout << "Setting " << newSinks.size() << " new sinks." << std::endl; // Modify the list of sinks so it can be retrieved by the MainWindow after the segmentation is finished this->Sinks.insert(this->Sinks.end(), newSinks.begin(), newSinks.end()); UpdateSelections(); }