int main() { FloatVectorImageType::Pointer image = FloatVectorImageType::New(); Testing::GetBlankImage(image.GetPointer(), 4); Mask::Pointer mask = Mask::New(); Testing::GetFullyValidMask(mask.GetPointer()); UnsignedCharScalarImageType::Pointer manualPriorityImage = UnsignedCharScalarImageType::New(); Testing::GetBlankImage(manualPriorityImage.GetPointer()); unsigned int patchRadius = 5; typedef PriorityConfidence ConfidencePriorityType; ConfidencePriorityType priorityConfidence(mask, patchRadius); PriorityManual<itk::Index<2>, UnsignedCharScalarImageType, ConfidencePriorityType> priority(manualPriorityImage, &priorityConfidence); itk::Index<2> filledPixel = {{0,0}}; priority.Update(filledPixel); priority.SetManualPriorityImage(manualPriorityImage); itk::Index<2> queryPixel = {{0,0}}; priority.ComputePriority(queryPixel); return EXIT_SUCCESS; }
void WriteImagePixelsToRGBSpace(const FloatVectorImageType::Pointer image, const std::string& outputFileName) { std::cout << "WriteImagePixelsToRGBSpace()" << std::endl; vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); colors->SetName("Colors"); colors->SetNumberOfComponents(3); itk::ImageRegionConstIterator<FloatVectorImageType> imageIterator(image, image->GetLargestPossibleRegion()); while(!imageIterator.IsAtEnd()) { FloatVectorImageType::PixelType pixel = imageIterator.Get(); points->InsertNextPoint(pixel[0], pixel[1], pixel[2]); // TODO: Narrowing conversion warning //unsigned char color[3] = {pixel[0], pixel[1], pixel[2]}; unsigned char color[3]; // TODO: Narrowing conversion warning colors->InsertNextTupleValue(color); ++imageIterator; } vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); polyData->SetPoints(points); polyData->GetPointData()->SetScalars(colors); vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New(); glyphFilter->SetInputData(polyData); glyphFilter->Update(); vtkSmartPointer<vtkXMLPolyDataWriter> writer = vtkSmartPointer<vtkXMLPolyDataWriter>::New(); writer->SetInputConnection(glyphFilter->GetOutputPort()); writer->SetFileName(outputFileName.c_str()); writer->Write(); }
int main() { FloatVectorImageType::Pointer image = FloatVectorImageType::New(); Testing::GetBlankImage(image.GetPointer(), 4); Mask::Pointer mask = Mask::New(); Testing::GetFullyValidMask(mask.GetPointer()); unsigned int patchRadius = 5; PriorityDepth<FloatVectorImageType> priority(image, mask, patchRadius); itk::Index<2> filledPixel = {{0,0}}; priority.Update(filledPixel); itk::Index<2> queryPixel = {{0,0}}; priority.ComputePriority(queryPixel); return EXIT_SUCCESS; }
// Convert a vector ITK image to a VTK image for display void ITKImagetoVTKImage(FloatVectorImageType::Pointer image, vtkImageData* outputImage) { std::cout << "ITKImagetoVTKImage()" << std::endl; if(image->GetNumberOfComponentsPerPixel() >= 3) { ITKImagetoVTKRGBImage(image, outputImage); } else { ITKImagetoVTKMagnitudeImage(image, outputImage); } }
int main(int argc, char *argv[]) { if(argc < 3) { throw std::runtime_error("Required arguments: inputFileName outputPrefix"); } std::string inputFileName = argv[1]; std::string outputPrefix = argv[2]; std::cout << "Input: " << inputFileName << std::endl; std::cout << "Output prefix: " << outputPrefix << std::endl; typedef itk::ImageFileReader<FloatVectorImageType> ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName(inputFileName); reader->Update(); ITKHelpers::WriteVectorImageAsRGB(reader->GetOutput(), outputPrefix + "/Image.mha"); WriteImagePixelsToRGBSpace(reader->GetOutput(), outputPrefix + "/ImageColors.vtp"); WriteClusteredPixelsInRGBSpace(reader->GetOutput(), 20, outputPrefix + "/ImageColorsClustered.vtp"); FloatVectorImageType::Pointer blurred = FloatVectorImageType::New(); //float blurVariance = 2.0f; // almost no visible blurring //float blurVariance = 10.0f; // slight blurring of concrete //float blurVariance = 30.0f; // TODO: Update this call to the new API //Helpers::AnisotropicBlurAllChannels<FloatVectorImageType>(reader->GetOutput(), blurred, blurVariance); ITKHelpers::WriteVectorImageAsRGB(blurred.GetPointer(), outputPrefix + "/BlurredImage.mha"); WriteImagePixelsToRGBSpace(blurred, outputPrefix + "/BlurredImageColors.vtp"); WriteClusteredPixelsInRGBSpace(blurred, 20, outputPrefix + "/BlurredImageColorsClustered.vtp"); return EXIT_SUCCESS; }
void WriteClusteredPixelsInRGBSpace(const FloatVectorImageType::Pointer image, const unsigned int numberOfClusters, const std::string& outputFileName) { std::cout << "WriteClusteredPixelsInRGBSpace()" << std::endl; ClusterColorsAdaptive clusterColors; clusterColors.SetNumberOfColors(numberOfClusters); clusterColors.ConstructFromImage(image); vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkUnsignedCharArray> colorsVTK = vtkSmartPointer<vtkUnsignedCharArray>::New(); colorsVTK->SetName("Colors"); colorsVTK->SetNumberOfComponents(3); vtkSmartPointer<vtkUnsignedIntArray> ids = vtkSmartPointer<vtkUnsignedIntArray>::New(); ids->SetName("Ids"); ids->SetNumberOfComponents(1); ColorMeasurementVectorType queryPoint; std::vector<ColorMeasurementVectorType> colors = clusterColors.GetColors(); itk::ImageRegionConstIterator<FloatVectorImageType> imageIterator(image, image->GetLargestPossibleRegion()); while(!imageIterator.IsAtEnd()) { FloatVectorImageType::PixelType pixel = imageIterator.Get(); queryPoint[0] = pixel[0]; queryPoint[1] = pixel[1]; queryPoint[2] = pixel[2]; ClusterColors::TreeType::InstanceIdentifierVectorType neighbors; clusterColors.GetKDTree()->Search( queryPoint, 1u, neighbors ); points->InsertNextPoint(pixel[0], pixel[1], pixel[2]); // TODO: Narrowing conversion warning //unsigned char color[3] = {colors[neighbors[0]][0], colors[neighbors[0]][1], colors[neighbors[0]][2]}; unsigned char color[3]; // TODO: placeholder so it will compile colorsVTK->InsertNextTupleValue(color); ids->InsertNextValue(neighbors[0]); ++imageIterator; } vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); polyData->SetPoints(points); polyData->GetPointData()->SetScalars(colorsVTK); polyData->GetPointData()->AddArray(ids); vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter = vtkSmartPointer<vtkVertexGlyphFilter>::New(); glyphFilter->SetInputData(polyData); glyphFilter->Update(); vtkSmartPointer<vtkXMLPolyDataWriter> writer = vtkSmartPointer<vtkXMLPolyDataWriter>::New(); writer->SetInputConnection(glyphFilter->GetOutputPort()); writer->SetFileName(outputFileName.c_str()); writer->Write(); }
// Convert a vector ITK image to a VTK image for display void ITKImagetoVTKRGBImage(FloatVectorImageType::Pointer image, vtkImageData* outputImage) { // This function assumes an ND (with N>3) image has the first 3 channels as RGB and extra information in the remaining channels. //std::cout << "ITKImagetoVTKRGBImage()" << std::endl; if(image->GetNumberOfComponentsPerPixel() < 3) { std::stringstream ss; ss << "The input image has " << image->GetNumberOfComponentsPerPixel() << " components, but at least 3 are required."; throw std::runtime_error(ss.str()); } // Setup and allocate the image data outputImage->SetNumberOfScalarComponents(3); outputImage->SetScalarTypeToUnsignedChar(); outputImage->SetDimensions(image->GetLargestPossibleRegion().GetSize()[0], image->GetLargestPossibleRegion().GetSize()[1], 1); outputImage->AllocateScalars(); // Copy all of the input image pixels to the output image itk::ImageRegionConstIteratorWithIndex<FloatVectorImageType> imageIterator(image,image->GetLargestPossibleRegion()); imageIterator.GoToBegin(); while(!imageIterator.IsAtEnd()) { unsigned char* pixel = static_cast<unsigned char*>(outputImage->GetScalarPointer(imageIterator.GetIndex()[0], imageIterator.GetIndex()[1],0)); for(unsigned int component = 0; component < 3; component++) { pixel[component] = static_cast<unsigned char>(imageIterator.Get()[component]); } ++imageIterator; } }
// Convert a vector ITK image to a VTK image for display void ITKImagetoVTKMagnitudeImage(FloatVectorImageType::Pointer image, vtkImageData* outputImage) { std::cout << "ITKImagetoVTKMagnitudeImage()" << std::endl; // Compute the magnitude of the ITK image typedef itk::VectorMagnitudeImageFilter< FloatVectorImageType, FloatScalarImageType > VectorMagnitudeFilterType; // Create and setup a magnitude filter VectorMagnitudeFilterType::Pointer magnitudeFilter = VectorMagnitudeFilterType::New(); magnitudeFilter->SetInput( image ); magnitudeFilter->Update(); // Rescale and cast for display typedef itk::RescaleIntensityImageFilter< FloatScalarImageType, UnsignedCharScalarImageType > RescaleFilterType; RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New(); rescaleFilter->SetOutputMinimum(0); rescaleFilter->SetOutputMaximum(255); rescaleFilter->SetInput( magnitudeFilter->GetOutput() ); rescaleFilter->Update(); // Setup and allocate the VTK image outputImage->SetNumberOfScalarComponents(1); outputImage->SetScalarTypeToUnsignedChar(); outputImage->SetDimensions(image->GetLargestPossibleRegion().GetSize()[0], image->GetLargestPossibleRegion().GetSize()[1], 1); outputImage->AllocateScalars(); // Copy all of the scaled magnitudes to the output image itk::ImageRegionConstIteratorWithIndex<UnsignedCharScalarImageType> imageIterator(rescaleFilter->GetOutput(), rescaleFilter->GetOutput()->GetLargestPossibleRegion()); imageIterator.GoToBegin(); while(!imageIterator.IsAtEnd()) { unsigned char* pixel = static_cast<unsigned char*>(outputImage->GetScalarPointer(imageIterator.GetIndex()[0], imageIterator.GetIndex()[1],0)); pixel[0] = imageIterator.Get(); ++imageIterator; } }
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 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 PartialPatchVectorComparison() { std::cout << "PartialPatchVectorComparison()" << std::endl; const unsigned int dimension = 3; FloatVectorImageType::Pointer vectorImage = FloatVectorImageType::New(); Testing::GetBlankImage<FloatVectorImageType>(vectorImage, dimension); // Make the left half of the image (0,0,0) and the right half (5,6,7) itk::ImageRegionIterator<FloatVectorImageType> imageIterator(vectorImage, vectorImage->GetLargestPossibleRegion()); itk::VariableLengthVector<float> leftHalfPixel; leftHalfPixel.SetSize(dimension); leftHalfPixel.Fill(0); itk::VariableLengthVector<float> rightHalfPixel; rightHalfPixel.SetSize(dimension); rightHalfPixel[0] = 5; rightHalfPixel[1] = 6; rightHalfPixel[2] = 7; while(!imageIterator.IsAtEnd()) { if(imageIterator.GetIndex()[0] < static_cast<int>(vectorImage->GetLargestPossibleRegion().GetSize()[0]/2)) { imageIterator.Set(leftHalfPixel); } else { imageIterator.Set(rightHalfPixel); } ++imageIterator; } itk::Size<2> patchSize; patchSize.Fill(10); // Full patches differ std::cout << "Full patch different test." << std::endl; { itk::Index<2> sourceCorner; sourceCorner.Fill(0); itk::ImageRegion<2> sourceRegion(sourceCorner, patchSize); ImagePatchPixelDescriptor<FloatVectorImageType> sourcePatch(vectorImage, sourceRegion, true); itk::Index<2> targetCorner; targetCorner.Fill(vectorImage->GetLargestPossibleRegion().GetSize()[0]/2 + 4); // No magic about 4, just want a patch on the right side of the image itk::ImageRegion<2> targetRegion(targetCorner, patchSize); ImagePatchPixelDescriptor<FloatVectorImageType> targetPatch(vectorImage, targetRegion, true); PatchPair<FloatVectorImageType> patchPair(&sourcePatch, targetPatch); PatchDifferencePixelWiseSum<FloatVectorImageType, PixelDifference> vector_patchDifferencePixelWiseSum; vector_patchDifferencePixelWiseSum.SetImage(vectorImage); float difference = vector_patchDifferencePixelWiseSum.Difference(patchPair); float correctDifference = targetRegion.GetNumberOfPixels() * 18; // 18 = 5+6+7, the sum of the elements of 'rightHalfPixel' if(difference != correctDifference) { std::stringstream ss; ss << "Difference " << difference << " does not match correctDifference " << correctDifference; throw std::runtime_error(ss.str()); } } // Full patches identical std::cout << "Identical patch test." << std::endl; { itk::Index<2> sourceCorner; sourceCorner.Fill(5); itk::ImageRegion<2> sourceRegion(sourceCorner, patchSize); ImagePatchPixelDescriptor<FloatVectorImageType> sourcePatch(vectorImage, sourceRegion, true); itk::Index<2> targetCorner; targetCorner.Fill(5); itk::ImageRegion<2> targetRegion(targetCorner, patchSize); ImagePatchPixelDescriptor<FloatVectorImageType> targetPatch(vectorImage, targetRegion, true); PatchPair<FloatVectorImageType> patchPair(&sourcePatch, targetPatch); PatchDifferencePixelWiseSum<FloatVectorImageType, PixelDifference> vector_patchDifferencePixelWiseSum; vector_patchDifferencePixelWiseSum.SetImage(vectorImage); float difference = vector_patchDifferencePixelWiseSum.Difference(patchPair); float correctDifference = 0; if(difference != correctDifference) { std::stringstream ss; ss << "Difference " << difference << " does not match correctDifference " << correctDifference; throw std::runtime_error(ss.str()); } } }
bool TestHasBracketOperator() { { typedef itk::CovariantVector<int, 3> IntVectorType; static_assert(Helpers::HasBracketOperator<IntVectorType>::value, "TestHasBracketOperator for CovariantVector<int, 3> failed!"); } { typedef itk::CovariantVector<unsigned char, 3> UCharVectorType; static_assert(Helpers::HasBracketOperator<UCharVectorType>::value, "TestHasBracketOperator for CovariantVector<unsigned char, 3> failed!"); } { typedef itk::CovariantVector<float, 3> FloatVectorType; static_assert(Helpers::HasBracketOperator<FloatVectorType>::value, "TestHasBracketOperator for CovariantVector<float, 3> failed!"); } { typedef itk::Image<itk::CovariantVector<float, 3>, 2> FloatVectorImageType; static_assert(Helpers::HasBracketOperator<FloatVectorImageType::PixelType>::value, "TestHasBracketOperator for CovariantVector<float, 3> failed!"); } { typedef itk::Image<itk::CovariantVector<float, 3>, 2> FloatVectorImageType; FloatVectorImageType::Pointer image = FloatVectorImageType::New(); TestHasBracketOperator_Template(image.GetPointer()); } { typedef itk::Image<itk::CovariantVector<float, 3>, 2> FloatVectorImageType; itk::SmartPointer<FloatVectorImageType> image = FloatVectorImageType::New(); TestHasBracketOperator_Template(image.GetPointer()); TestHasBracketOperator_ConstTemplate(image.GetPointer()); } { typedef itk::Image<itk::CovariantVector<float, 3>, 2> FloatVectorImageType; TestHasBracketOperator_Template2<FloatVectorImageType>(); } { typedef itk::VariableLengthVector<int> VectorType; static_assert(Helpers::HasBracketOperator<VectorType>::value, "TestHasBracketOperator for VariableLengthVector failed!"); } { typedef std::vector<int> VectorType; static_assert(Helpers::HasBracketOperator<VectorType>::value, "TestHasBracketOperator for std::vector failed!"); } // This (intentionally) fails // { // static_assert(Helpers::HasBracketOperator<float>::value, // "TestHasBracketOperator for float failed!"); // } return true; }
int main(int argc, char *argv[]) { unsigned int t = time(NULL); srand(t); itk::Size<2> size; size.Fill(10); 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] = RandomFloat(); pixel[1] = RandomFloat(); pixel[2] = RandomFloat(); imageIterator.Set(pixel); ++imageIterator; } } // 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(); // Write the mask itk::ImageFileWriter<Mask>::Pointer maskWriter = itk::ImageFileWriter<Mask>::New(); maskWriter->SetFileName("mask.png"); maskWriter->SetInput(mask); maskWriter->Update(); unsigned int patchRadius = 1; // Create source patches itk::ImageRegionConstIterator<FloatVectorImageType> imageIterator(image, image->GetLargestPossibleRegion()); std::vector<itk::ImageRegion<2> > sourcePatches; while(!imageIterator.IsAtEnd()) { itk::Index<2> currentPixel = imageIterator.GetIndex(); itk::ImageRegion<2> region = GetRegionInRadiusAroundPixel(currentPixel, patchRadius); if(image->GetLargestPossibleRegion().IsInside(region)) { sourcePatches.push_back(region); } ++imageIterator; } itk::Size<2> targetSize; targetSize.Fill(patchRadius * 2 + 1); itk::Index<2> targetIndex; targetIndex.Fill(3); itk::ImageRegion<2> targetRegion(targetIndex, targetSize); SelfPatchCompare patchCompare; patchCompare.SetImage(image); patchCompare.SetMask(mask); patchCompare.SetSourceRegions(sourcePatches); patchCompare.SetTargetRegion(targetRegion); patchCompare.ComputeOffsets(); //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; }