int main(int argc, char *argv[]) { // Create the graph typedef boost::grid_graph<2> VertexListGraphType; const unsigned int graphSideLength = 10; boost::array<std::size_t, 2> graphSideLengths = { { graphSideLength, graphSideLength } }; VertexListGraphType graph(graphSideLengths); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; IndexMapType indexMap(get(boost::vertex_index, graph)); // Create the descriptor maps. typedef boost::vector_property_map<FeatureVectorPixelDescriptor, IndexMapType> DescriptorMapType1; DescriptorMapType1 descriptorMap1(num_vertices(graph), indexMap); typedef boost::vector_property_map<FeatureVectorPixelDescriptor, IndexMapType> DescriptorMapType2; DescriptorMapType2 descriptorMap2(num_vertices(graph), indexMap); typedef LinearSearchKNNProperty<DescriptorMapType1, FeatureVectorDifference> KNNSearchType; KNNSearchType linearSearchKNN(descriptorMap1, 1000); typedef LinearSearchBestProperty<DescriptorMapType2, FeatureVectorDifference> BestSearchType; BestSearchType linearSearchBest(descriptorMap2); TwoStepNearestNeighbor<KNNSearchType, BestSearchType> twoStepNearestNeighbor(linearSearchKNN, linearSearchBest); return EXIT_SUCCESS; }
/****************************************************************************** * Remaps the bonds after some of the particles have been deleted. * Dangling bonds are removed too. ******************************************************************************/ void BondsObject::particlesDeleted(const boost::dynamic_bitset<>& deletedParticlesMask) { // Build map that maps old particle indices to new indices. std::vector<size_t> indexMap(deletedParticlesMask.size()); auto index = indexMap.begin(); size_t oldParticleCount = deletedParticlesMask.size(); size_t newParticleCount = 0; for(size_t i = 0; i < deletedParticlesMask.size(); i++) *index++ = deletedParticlesMask.test(i) ? std::numeric_limits<size_t>::max() : newParticleCount++; auto result = modifiableStorage()->begin(); auto bond = modifiableStorage()->begin(); auto last = modifiableStorage()->end(); for(; bond != last; ++bond) { // Remove invalid bonds. if(bond->index1 >= oldParticleCount || bond->index2 >= oldParticleCount) continue; // Remove dangling bonds whose particles have gone. if(deletedParticlesMask.test(bond->index1) || deletedParticlesMask.test(bond->index2)) continue; // Keep but remap particle indices. result->pbcShift = bond->pbcShift; result->index1 = indexMap[bond->index1]; result->index2 = indexMap[bond->index2]; ++result; } modifiableStorage()->erase(result, last); changed(); }
extern "C" jintArray Java_java_text_Bidi_ubidi_1reorderVisual(JNIEnv* env, jclass, jbyteArray javaLevels, jint length) { ScopedByteArrayRO levelBytes(env, javaLevels); if (levelBytes.get() == NULL) { return NULL; } const UBiDiLevel* levels = reinterpret_cast<const UBiDiLevel*>(levelBytes.get()); UniquePtr<int[]> indexMap(new int[length]); ubidi_reorderVisual(levels, length, &indexMap[0]); jintArray result = env->NewIntArray(length); env->SetIntArrayRegion(result, 0, length, &indexMap[0]); return result; }
std::vector<unsigned> intervalCompressor( std::vector<GenomeInterval>& intervals) { std::vector<GenomeInterval> intervals2; const unsigned count(intervals.size()); std::vector<bool> isTransfered(count,false); std::vector<unsigned> indexMap(count,0); for (unsigned headIndex(0); headIndex < count; ++headIndex) { if (isTransfered[headIndex]) continue; const unsigned headIndex2(intervals2.size()); isTransfered[headIndex] = true; indexMap[headIndex] = headIndex2; intervals2.push_back(intervals[headIndex]); GenomeInterval& headInterval(intervals2.back()); while (true) { bool isComplete(true); for (unsigned testIndex(headIndex+1); testIndex < count; ++testIndex) { if (isTransfered[testIndex]) continue; if (headInterval.isIntersect(intervals[testIndex])) { isTransfered[testIndex] = true; indexMap[testIndex] = headIndex2; headInterval.range.merge_range(intervals[testIndex].range); isComplete=false; break; } } if (isComplete) break; } } intervals = intervals2; return indexMap; }
void update() { std::vector<int> indexMap(constraintId); for (int id = 0; id < constraintId; ++id) { indexMap[id] = -1; } std::vector<int> freeIndex; for (int i = n; i >= 1; --i) { Checklist& list = checklists[i]; for (typename Checklist::iterator t = list.begin(); t != list.end(); ++t) { int id = t->index; if (indexMap[id] < 0) { if (freeIndex.empty()) { indexMap[id] = arraySize++; } else { indexMap[id] = freeIndex.back(); freeIndex.pop_back(); } } t->index = indexMap[id]; } for (typename Checklist::iterator t = list.begin(); t != list.end(); ++t) { if (t->finalChoice) { freeIndex.push_back(t->index); } } } this->setArraySize(arraySize); }
void TestDriver(typename itk::SmartPointer<TImage> originalImage, Mask::Pointer mask, const unsigned int patchHalfWidth) { /** Store the viewer here so that it is created in the GUI thread and persists. */ typedef BasicViewerWidget<TImage> BasicViewerWidgetType; std::shared_ptr<BasicViewerWidgetType> basicViewer(new BasicViewerWidgetType(originalImage, mask)); basicViewer->show(); typedef boost::grid_graph<2> VertexListGraphType; typedef DisplayVisitor<VertexListGraphType, TImage> DisplayVisitorType; std::shared_ptr<DisplayVisitorType> displayVisitor( new DisplayVisitorType(originalImage, mask, patchHalfWidth)); itk::ImageRegion<2> fullRegion = originalImage->GetLargestPossibleRegion(); // Blur the image typedef TImage BlurredImageType; // Usually the blurred image is the same type as the original image. typename BlurredImageType::Pointer blurredImage = BlurredImageType::New(); float blurVariance = 2.0f; MaskOperations::MaskedBlur(originalImage.GetPointer(), mask, blurVariance, blurredImage.GetPointer()); typedef ImagePatchPixelDescriptor<TImage> ImagePatchPixelDescriptorType; // Create the graph boost::array<std::size_t, 2> graphSideLengths = { { fullRegion.GetSize()[0], fullRegion.GetSize()[1] } }; std::shared_ptr<VertexListGraphType> graph(new VertexListGraphType(graphSideLengths)); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; std::shared_ptr<IndexMapType> indexMap(new IndexMapType(get(boost::vertex_index, *graph))); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<ImagePatchPixelDescriptorType, IndexMapType> ImagePatchDescriptorMapType; std::shared_ptr<ImagePatchDescriptorMapType> imagePatchDescriptorMap( new ImagePatchDescriptorMapType(num_vertices(*graph), *indexMap)); // Queue typedef IndirectPriorityQueue<VertexListGraphType> BoundaryNodeQueueType; std::shared_ptr<BoundaryNodeQueueType> boundaryNodeQueue(new BoundaryNodeQueueType(*graph)); // Create the descriptor visitor typedef ImagePatchDescriptorVisitor<VertexListGraphType, TImage, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType; std::shared_ptr<ImagePatchDescriptorVisitorType> imagePatchDescriptorVisitor( new ImagePatchDescriptorVisitorType(originalImage, mask, *imagePatchDescriptorMap, patchHalfWidth)); // If the hole is less than 15% of the patch, always accept the initial best match typedef HoleSizeAcceptanceVisitor<VertexListGraphType> HoleSizeAcceptanceVisitorType; std::shared_ptr<HoleSizeAcceptanceVisitorType> holeSizeAcceptanceVisitor(new HoleSizeAcceptanceVisitorType(mask, patchHalfWidth, .15)); // Create the priority function typedef PriorityCriminisi<TImage> PriorityType; std::shared_ptr<PriorityType> priorityFunction( new PriorityType(blurredImage, mask, patchHalfWidth)); // Create the inpainting visitor typedef InpaintingVisitor<VertexListGraphType, BoundaryNodeQueueType, ImagePatchDescriptorVisitorType, HoleSizeAcceptanceVisitorType, PriorityType> InpaintingVisitorType; std::shared_ptr<InpaintingVisitorType> inpaintingVisitor( new InpaintingVisitorType(mask, boundaryNodeQueue, imagePatchDescriptorVisitor, holeSizeAcceptanceVisitor, priorityFunction, patchHalfWidth, "InpaintingVisitor")); typedef SumSquaredPixelDifference<typename TImage::PixelType> PixelDifferenceType; typedef ImagePatchDifference<ImagePatchPixelDescriptorType, PixelDifferenceType > ImagePatchDifferenceType; // Create the nearest neighbor finders typedef LinearSearchKNNProperty<ImagePatchDescriptorMapType, ImagePatchDifferenceType > KNNSearchType; unsigned int numberOfKNN = 100; std::shared_ptr<KNNSearchType> knnSearch(new KNNSearchType(*imagePatchDescriptorMap, numberOfKNN)); // Run the remaining inpainting with interaction std::cout << "Running inpainting..." << std::endl; // QtConcurrent::run(boost::bind(InpaintingAlgorithmWithVerification< // VertexListGraphType, CompositeInpaintingVisitorType, // BoundaryNodeQueueType, KNNSearchType, BestSearchType, // ManualSearchType, CompositePatchInpainter>, // graph, compositeInpaintingVisitor, boundaryNodeQueue, knnSearch, // bestSearch, manualSearchBest, compositeInpainter)); // QtConcurrent::run(boost::bind(TestDriverFunction< // VertexListGraphType, CompositeInpaintingVisitorType, // BoundaryNodeQueueType, KNNSearchType, BestSearchType, // ManualSearchType, CompositePatchInpainter>, // graph, compositeInpaintingVisitor, boundaryNodeQueue, knnSearch, // bestSearch, manualSearchBest, compositeInpainter)); QtConcurrent::run(boost::bind(TestDriverFunction< VertexListGraphType, InpaintingVisitorType, BoundaryNodeQueueType, KNNSearchType>, graph, inpaintingVisitor, boundaryNodeQueue, knnSearch)); // QtConcurrent::run(boost::bind(TestDriverFunction< // VertexListGraphType, CompositeInpaintingVisitorType, // BoundaryNodeQueueType>, // graph, compositeInpaintingVisitor, boundaryNodeQueue)); // QtConcurrent::run(boost::bind(TestDriverFunction< // VertexListGraphType, CompositeInpaintingVisitorType>, // graph, compositeInpaintingVisitor)); // QtConcurrent::run(boost::bind(TestDriverFunction<VertexListGraphType>, graph)); }
// Run with: Data/trashcan.mha Data/trashcan_mask.mha 15 Data/trashcan.vtp Intensity filled.mha int main(int argc, char *argv[]) { // Verify arguments if(argc != 6) { std::cerr << "Required arguments: image.mha imageMask.mha patch_half_width normals.vts output.mha" << std::endl; std::cerr << "Input arguments: "; for(int i = 1; i < argc; ++i) { std::cerr << argv[i] << " "; } return EXIT_FAILURE; } // Parse arguments std::string imageFilename = argv[1]; std::string maskFilename = argv[2]; std::stringstream ssPatchRadius; ssPatchRadius << argv[3]; unsigned int patch_half_width = 0; ssPatchRadius >> patch_half_width; std::string normalsFileName = argv[4]; std::string outputFilename = argv[5]; // Output arguments std::cout << "Reading image: " << imageFilename << std::endl; std::cout << "Reading mask: " << maskFilename << std::endl; std::cout << "Patch half width: " << patch_half_width << std::endl; std::cout << "Reading normals: " << normalsFileName << std::endl; std::cout << "Output: " << outputFilename << std::endl; vtkSmartPointer<vtkXMLStructuredGridReader> structuredGridReader = vtkSmartPointer<vtkXMLStructuredGridReader>::New(); structuredGridReader->SetFileName(normalsFileName.c_str()); structuredGridReader->Update(); typedef FloatVectorImageType ImageType; typedef itk::ImageFileReader<ImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename); imageReader->Update(); ImageType::Pointer image = ImageType::New(); ITKHelpers::DeepCopy(imageReader->GetOutput(), image.GetPointer()); Mask::Pointer mask = Mask::New(); mask->Read(maskFilename); std::cout << "hole pixels: " << mask->CountHolePixels() << std::endl; std::cout << "valid pixels: " << mask->CountValidPixels() << std::endl; typedef ImagePatchPixelDescriptor<ImageType> ImagePatchPixelDescriptorType; typedef FeatureVectorPixelDescriptor FeatureVectorPixelDescriptorType; // Create the graph typedef boost::grid_graph<2> VertexListGraphType; boost::array<std::size_t, 2> graphSideLengths = { { imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[0], imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[1] } }; VertexListGraphType graph(graphSideLengths); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; IndexMapType indexMap(get(boost::vertex_index, graph)); // Create the priority map typedef boost::vector_property_map<float, IndexMapType> PriorityMapType; PriorityMapType priorityMap(num_vertices(graph), indexMap); // Create the node fill status map. Each pixel is either filled (true) or not filled (false). typedef boost::vector_property_map<bool, IndexMapType> FillStatusMapType; FillStatusMapType fillStatusMap(num_vertices(graph), indexMap); // Create the boundary status map. A node is on the current boundary if this property is true. // This property helps the boundaryNodeQueue because we can mark here if a node has become no longer // part of the boundary, so when the queue is popped we can check this property to see if it should // actually be processed. typedef boost::vector_property_map<bool, IndexMapType> BoundaryStatusMapType; BoundaryStatusMapType boundaryStatusMap(num_vertices(graph), indexMap); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<ImagePatchPixelDescriptorType, IndexMapType> ImagePatchDescriptorMapType; ImagePatchDescriptorMapType imagePatchDescriptorMap(num_vertices(graph), indexMap); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<FeatureVectorPixelDescriptorType, IndexMapType> FeatureVectorDescriptorMapType; FeatureVectorDescriptorMapType featureVectorDescriptorMap(num_vertices(graph), indexMap); // Create the patch inpainter. The inpainter needs to know the status of each pixel to determine if they should be inpainted. typedef MaskedGridPatchInpainter<FillStatusMapType> InpainterType; InpainterType patchInpainter(patch_half_width, fillStatusMap); // Create the priority function typedef PriorityRandom PriorityType; PriorityType priorityFunction; // Create the boundary node queue. The priority of each node is used to order the queue. typedef boost::vector_property_map<std::size_t, IndexMapType> IndexInHeapMap; IndexInHeapMap index_in_heap(indexMap); // Create the priority compare functor typedef std::less<float> PriorityCompareType; PriorityCompareType lessThanFunctor; typedef boost::d_ary_heap_indirect<VertexDescriptorType, 4, IndexInHeapMap, PriorityMapType, PriorityCompareType> BoundaryNodeQueueType; BoundaryNodeQueueType boundaryNodeQueue(priorityMap, index_in_heap, lessThanFunctor); // Create the descriptor visitors typedef FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitor<VertexListGraphType, FeatureVectorDescriptorMapType> FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitorType; FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitorType featureVectorPrecomputedStructuredGridNormalsDescriptorVisitor(featureVectorDescriptorMap, structuredGridReader->GetOutput()); typedef ImagePatchDescriptorVisitor<VertexListGraphType, ImageType, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType; ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(image, mask, imagePatchDescriptorMap, patch_half_width); typedef CompositeDescriptorVisitor<VertexListGraphType> CompositeDescriptorVisitorType; CompositeDescriptorVisitorType compositeDescriptorVisitor; compositeDescriptorVisitor.AddVisitor(&imagePatchDescriptorVisitor); compositeDescriptorVisitor.AddVisitor(&featureVectorPrecomputedStructuredGridNormalsDescriptorVisitor); // Create the inpainting visitor typedef InpaintingVisitor<VertexListGraphType, ImageType, BoundaryNodeQueueType, FillStatusMapType, CompositeDescriptorVisitorType, PriorityType, PriorityMapType, BoundaryStatusMapType> InpaintingVisitorType; InpaintingVisitorType inpaintingVisitor(image, mask, boundaryNodeQueue, fillStatusMap, compositeDescriptorVisitor, priorityMap, &priorityFunction, patch_half_width, boundaryStatusMap); InitializePriority(mask, boundaryNodeQueue, priorityMap, &priorityFunction, boundaryStatusMap); // Initialize the boundary node queue from the user provided mask image. InitializeFromMaskImage(mask, &inpaintingVisitor, graph, fillStatusMap); std::cout << "PatchBasedInpaintingNonInteractive: There are " << boundaryNodeQueue.size() << " nodes in the boundaryNodeQueue" << std::endl; // Create the nearest neighbor finder // typedef LinearSearchKNNProperty<FeatureVectorDescriptorMapType, FeatureVectorAngleDifference> KNNSearchType; // KNNSearchType linearSearchKNN(featureVectorDescriptorMap); typedef LinearSearchCriteriaProperty<FeatureVectorDescriptorMapType, FeatureVectorAngleDifference> ThresholdSearchType; //float maximumAngle = 0.34906585; // ~ 20 degrees float maximumAngle = 0.15; // ~ 10 degrees //float maximumAngle = 0.08; // ~ 5 degrees (this seems to be too strict) ThresholdSearchType thresholdSearchType(featureVectorDescriptorMap, maximumAngle); typedef LinearSearchBestProperty<ImagePatchDescriptorMapType, ImagePatchDifference<ImagePatchPixelDescriptorType> > BestSearchType; BestSearchType linearSearchBest(imagePatchDescriptorMap); TwoStepNearestNeighbor<ThresholdSearchType, BestSearchType> twoStepNearestNeighbor(thresholdSearchType, linearSearchBest); // Perform the inpainting std::cout << "Performing inpainting...: " << std::endl; inpainting_loop(graph, inpaintingVisitor, boundaryStatusMap, boundaryNodeQueue, twoStepNearestNeighbor, patchInpainter); HelpersOutput::WriteImage<ImageType>(image, outputFilename); return EXIT_SUCCESS; }
void LidarInpaintingHSVTextureVerification(TImage* const originalImage, Mask* const mask, const unsigned int patchHalfWidth, const unsigned int numberOfKNN, float slightBlurVariance = 1.0f, unsigned int searchRadius = 1000, float localRegionSizeMultiplier = 3.0f, float maxAllowedUsedPixelsRatio = 0.5f) { itk::ImageRegion<2> fullRegion = originalImage->GetLargestPossibleRegion(); // Extract the RGB image typedef itk::Image<itk::CovariantVector<float, 3>, 2> RGBImageType; std::vector<unsigned int> firstThreeChannels = {0,1,2}; RGBImageType::Pointer rgbImage = RGBImageType::New(); ITKHelpers::ExtractChannels(originalImage, firstThreeChannels, rgbImage.GetPointer()); // Create the HSV image typedef itk::Image<itk::CovariantVector<float, 3>, 2> HSVImageType; HSVImageType::Pointer hsvImage = HSVImageType::New(); ITKVTKHelpers::ConvertRGBtoHSV(rgbImage.GetPointer(), hsvImage.GetPointer()); ITKHelpers::WriteImage(hsvImage.GetPointer(), "HSVImage.mha"); // Stack the HSV image with the original rest of the channels typedef itk::Image<itk::CovariantVector<float, 5>, 2> HSVDxDyImageType; HSVDxDyImageType::Pointer hsvDxDyImage = HSVDxDyImageType::New(); ITKHelpers::DeepCopy(originalImage, hsvDxDyImage.GetPointer()); ITKHelpers::ReplaceChannels(hsvDxDyImage.GetPointer(), firstThreeChannels, hsvImage.GetPointer()); // Blur the image for gradient computation stability (Criminisi's data term) RGBImageType::Pointer blurredRGBImage = RGBImageType::New(); float blurVariance = 2.0f; MaskOperations::MaskedBlur(rgbImage.GetPointer(), mask, blurVariance, blurredRGBImage.GetPointer()); ITKHelpers::WriteRGBImage(blurredRGBImage.GetPointer(), "BlurredRGBImage.png"); // Blur the image slightly so that the SSD comparisons are not so noisy typename HSVDxDyImageType::Pointer slightlyBlurredHSVDxDyImage = TImage::New(); MaskOperations::MaskedBlur(hsvDxDyImage.GetPointer(), mask, slightBlurVariance, slightlyBlurredHSVDxDyImage.GetPointer()); ITKHelpers::WriteImage(slightlyBlurredHSVDxDyImage.GetPointer(), "SlightlyBlurredHSVDxDyImage.mha"); // Create the graph typedef ImagePatchPixelDescriptor<TImage> ImagePatchPixelDescriptorType; typedef boost::grid_graph<2> VertexListGraphType; // We can't make this a signed type (size_t versus int) because we allow negative boost::array<std::size_t, 2> graphSideLengths = { { fullRegion.GetSize()[0], fullRegion.GetSize()[1] } }; VertexListGraphType graph(graphSideLengths); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; typedef boost::graph_traits<VertexListGraphType>::vertex_iterator VertexIteratorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; IndexMapType indexMap(get(boost::vertex_index, graph)); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<ImagePatchPixelDescriptorType, IndexMapType> ImagePatchDescriptorMapType; ImagePatchDescriptorMapType imagePatchDescriptorMap(num_vertices(graph), indexMap); // Create the patch inpainter. typedef PatchInpainter<TImage> OriginalImageInpainterType; OriginalImageInpainterType originalImagePatchInpainter(patchHalfWidth, originalImage, mask); originalImagePatchInpainter.SetDebugImages(true); originalImagePatchInpainter.SetImageName("RGB"); // Create an inpainter for the HSV image. typedef PatchInpainter<HSVImageType> HSVImageInpainterType; HSVImageInpainterType hsvImagePatchInpainter(patchHalfWidth, hsvImage, mask); // Create an inpainter for the RGB image. typedef PatchInpainter<RGBImageType> RGBImageInpainterType; RGBImageInpainterType rgbImagePatchInpainter(patchHalfWidth, rgbImage, mask); // Create an inpainter for the blurred image. typedef PatchInpainter<RGBImageType> BlurredImageInpainterType; BlurredImageInpainterType blurredRGBImagePatchInpainter(patchHalfWidth, blurredRGBImage, mask); // Create an inpainter for the slightly blurred image. typedef PatchInpainter<TImage> SlightlyBlurredHSVDxDyImageImageInpainterType; SlightlyBlurredHSVDxDyImageImageInpainterType slightlyBlurredHSVDxDyImageImagePatchInpainter(patchHalfWidth, slightlyBlurredHSVDxDyImage, mask); // Create a composite inpainter. (Note: the mask is inpainted in InpaintingVisitor::FinishVertex) CompositePatchInpainter inpainter; inpainter.AddInpainter(&originalImagePatchInpainter); inpainter.AddInpainter(&hsvImagePatchInpainter); inpainter.AddInpainter(&blurredRGBImagePatchInpainter); inpainter.AddInpainter(&slightlyBlurredHSVDxDyImageImagePatchInpainter); inpainter.AddInpainter(&rgbImagePatchInpainter); // Create the priority function typedef PriorityCriminisi<RGBImageType> PriorityType; PriorityType priorityFunction(blurredRGBImage, mask, patchHalfWidth); // priorityFunction.SetDebugLevel(1); // Queue typedef IndirectPriorityQueue<VertexListGraphType> BoundaryNodeQueueType; BoundaryNodeQueueType boundaryNodeQueue(graph); // Create the descriptor visitor (used for SSD comparisons). typedef ImagePatchDescriptorVisitor<VertexListGraphType, TImage, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType; // ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(originalImage, mask, // imagePatchDescriptorMap, patchHalfWidth); // Use the non-blurred image for the SSD comparisons ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(slightlyBlurredHSVDxDyImage, mask, imagePatchDescriptorMap, patchHalfWidth); // Use the slightly blurred HSV image for the SSD comparisons. Make sure to use a *HSVSSD difference functor so the H differences are treated appropriately! typedef DefaultAcceptanceVisitor<VertexListGraphType> AcceptanceVisitorType; AcceptanceVisitorType acceptanceVisitor; // Create the inpainting visitor. (The mask is inpainted in FinishVertex) typedef InpaintingVisitor<VertexListGraphType, BoundaryNodeQueueType, ImagePatchDescriptorVisitorType, AcceptanceVisitorType, PriorityType, TImage> InpaintingVisitorType; InpaintingVisitorType inpaintingVisitor(mask, boundaryNodeQueue, imagePatchDescriptorVisitor, acceptanceVisitor, &priorityFunction, patchHalfWidth, "InpaintingVisitor", originalImage); inpaintingVisitor.SetDebugImages(true); // This produces PatchesCopied* images showing where patches were copied from/to at each iteration // inpaintingVisitor.SetAllowNewPatches(false); inpaintingVisitor.SetAllowNewPatches(true); // we can do this as long as we use one of the LinearSearchKNNProperty*Reuse (like LinearSearchKNNPropertyLimitLocalReuse) in the steps below InitializePriority(mask, boundaryNodeQueue, &priorityFunction); // Initialize the boundary node queue from the user provided mask image. InitializeFromMaskImage<InpaintingVisitorType, VertexDescriptorType>(mask, &inpaintingVisitor); std::cout << "PatchBasedInpaintingNonInteractive: There are " << boundaryNodeQueue.CountValidNodes() << " nodes in the boundaryNodeQueue" << std::endl; #define DUseWeightedDifference #ifdef DUseWeightedDifference // The absolute value of the depth derivative range is usually about [0,12], so to make // it comparable to to the color image channel range of [0,255], we multiply by 255/12 ~= 20. // float depthDerivativeWeight = 20.0f; // This should not be computed "by eye" by looking at the Dx and Dy channels of the PTX scan, because there are typically // huge depth discontinuties around the objects that are going to be inpainted. We'd have to look at the masked version of this // image to determine the min/max values of the unmasked pixels. They will be much smaller than the min/max values of the original // image, which will make the depth derivative weights much higher (~100 or so) // std::vector<typename TImage::PixelType> channelMins = ITKHelpers::ComputeMinOfAllChannels(originalImage); // std::vector<typename TImage::PixelType> channelMaxs = ITKHelpers::ComputeMaxOfAllChannels(originalImage); typename TImage::PixelType channelMins; ITKHelpers::ComputeMinOfAllChannels(originalImage, channelMins); typename TImage::PixelType channelMaxs; ITKHelpers::ComputeMaxOfAllChannels(originalImage, channelMaxs); float minX = fabs(channelMins[3]); float maxX = fabs(channelMaxs[3]); float maxValueX = std::max(minX, maxX); std::cout << "maxValueX = " << maxValueX << std::endl; float depthDerivativeWeightX = 255.0f / maxValueX; std::cout << "Computed depthDerivativeWeightX = " << depthDerivativeWeightX << std::endl; float minY = fabs(channelMins[4]); float maxY = fabs(channelMaxs[4]); float maxValueY = std::max(minY, maxY); std::cout << "maxValueY = " << maxValueY << std::endl; float depthDerivativeWeightY = 255.0f / maxValueY; std::cout << "Computed depthDerivativeWeightY = " << depthDerivativeWeightY << std::endl; // Use all channels std::vector<float> weights = {1.0f, 1.0f, 1.0f, depthDerivativeWeightX, depthDerivativeWeightY}; // typedef WeightedSumSquaredPixelDifference<typename TImage::PixelType> PixelDifferenceType; typedef WeightedHSVSSDFull<typename TImage::PixelType> FullPixelDifferenceType; FullPixelDifferenceType fullPixelDifferenceFunctor(weights); typedef ImagePatchDifference<ImagePatchPixelDescriptorType, FullPixelDifferenceType > FullPatchDifferenceType; FullPatchDifferenceType fullPatchDifferenceFunctor(fullPixelDifferenceFunctor); // Use only the first 3 channels typedef HSVSSD<typename TImage::PixelType> First3PixelDifferenceType; First3PixelDifferenceType first3PixelDifferenceFunctor; typedef ImagePatchDifference<ImagePatchPixelDescriptorType, First3PixelDifferenceType > First3PatchDifferenceType; First3PatchDifferenceType first3PatchDifferenceFunctor(first3PixelDifferenceFunctor); #else // Use an unweighted pixel difference typedef ImagePatchDifference<ImagePatchPixelDescriptorType, SumSquaredPixelDifference<typename TImage::PixelType> > PatchDifferenceType; PatchDifferenceType patchDifferenceFunctor; #endif //#define DAllowReuse // comment/uncomment this line to toggle allowing patches to be used as the source patch more than once #ifdef DAllowReuse // Create the first (KNN) neighbor finder typedef LinearSearchKNNProperty<ImagePatchDescriptorMapType, PatchDifferenceType> KNNSearchType; KNNSearchType linearSearchKNN(imagePatchDescriptorMap, numberOfKNN, patchDifferenceFunctor); #else typedef LinearSearchKNNPropertyLimitLocalReuse<ImagePatchDescriptorMapType, FullPatchDifferenceType, RGBImageType> KNNSearchType; KNNSearchType linearSearchKNN(imagePatchDescriptorMap, mask, numberOfKNN, localRegionSizeMultiplier, maxAllowedUsedPixelsRatio, fullPatchDifferenceFunctor, inpaintingVisitor.GetSourcePixelMapImage(), rgbImage.GetPointer()); linearSearchKNN.SetDebugImages(true); linearSearchKNN.SetDebugScreenOutputs(true); #endif //#else // This works the best, but is less useful for demonstrations // typedef LinearSearchKNNPropertyLimitLocalReuse<ImagePatchDescriptorMapType, FullPatchDifferenceType, RGBImageType> FullPixelKNNSearchType; // FullPixelKNNSearchType fullPixelSearchKNN(imagePatchDescriptorMap, mask, numberOfKNN, localRegionSizeMultiplier, maxAllowedUsedPixelsRatio, // fullPatchDifferenceFunctor, inpaintingVisitor.GetSourcePixelMapImage(), // rgbImage.GetPointer()); // fullPixelSearchKNN.SetDebugImages(true); // fullPixelSearchKNN.SetDebugScreenOutputs(true); // typedef LinearSearchKNNPropertyLimitLocalReuse<ImagePatchDescriptorMapType, First3PatchDifferenceType, RGBImageType> First3PixelKNNSearchType; // First3PixelKNNSearchType first3SearchKNN(imagePatchDescriptorMap, mask, numberOfKNN, localRegionSizeMultiplier, maxAllowedUsedPixelsRatio, // first3PatchDifferenceFunctor, inpaintingVisitor.GetSourcePixelMapImage(), // rgbImage.GetPointer()); // first3SearchKNN.SetDebugScreenOutputs(true); //// typedef LinearSearchKNNProperty<ImagePatchDescriptorMapType, First3PatchDifferenceType> First3PixelKNNSearchType; //// First3PixelKNNSearchType first3SearchKNN(imagePatchDescriptorMap, numberOfKNN, //// first3PatchDifferenceFunctor); //// first3SearchKNN.SetDebugImages(true); // typedef LinearSearchKNNPropertyCombine<FullPixelKNNSearchType, First3PixelKNNSearchType> KNNSearchType; // KNNSearchType linearSearchKNN(fullPixelSearchKNN, first3SearchKNN); //#endif // Setup the second (1-NN) neighbor finder typedef std::vector<VertexDescriptorType>::iterator VertexDescriptorVectorIteratorType; // This is templated on TImage because we need it to write out debug patches from this searcher (since we are not using an RGB image to compute the histograms) // typedef LinearSearchBestTexture<ImagePatchDescriptorMapType, HSVImageType, // VertexDescriptorVectorIteratorType, TImage> BestSearchType; // Use the histogram of the gradient magnitudes of a scalar represetnation of the image (e.g. magnitude image) // typedef LinearSearchBestLidarTextureDerivatives<ImagePatchDescriptorMapType, HSVImageType, // VertexDescriptorVectorIteratorType, TImage> BestSearchType; // Use the concatenated histograms of the absolute value of the derivatives of each channel // typedef LinearSearchBestLidarHSVTextureGradient<ImagePatchDescriptorMapType, HSVDxDyImageType, // VertexDescriptorVectorIteratorType, RGBImageType> BestSearchType; // Use the concatenated histograms of the gradient magnitudes of each channel. This HSVDxDyImageType must match the hsvDxDyImage provided below typedef LinearSearchBestLidarHSVTextureGradientWithSort<ImagePatchDescriptorMapType, HSVDxDyImageType, VertexDescriptorVectorIteratorType, RGBImageType> BestSearchType; // Use the concatenated histograms of the gradient magnitudes of each channel. This HSVDxDyImageType must match the hsvDxDyImage provided below. Also sort the patches for demonstrative output purposes. // BestSearchType linearSearchBest(imagePatchDescriptorMap, hsvDxDyImage.GetPointer(), mask); // use non-blurred for texture sorting Debug bestSearchTypeDebug; bestSearchTypeDebug.SetDebugScreenOutputs(true); // bestSearchTypeDebug.SetDebugImages(true); // linearSearchBest.SetDebugOutputs(true); // linearSearchBest.SetDebugImages(true); // use slightly blurred for texture sorting BestSearchType linearSearchBest(imagePatchDescriptorMap, slightlyBlurredHSVDxDyImage.GetPointer(), mask, rgbImage.GetPointer(), bestSearchTypeDebug); // linearSearchBest.SetDebugImages(false); linearSearchBest.SetDebugImages(true); // This produces BestPatch* images showing the list of the top K patches that were passed to the BestSearch functor // Setup the two step neighbor finder TwoStepNearestNeighbor<KNNSearchType, BestSearchType> twoStepNearestNeighbor(linearSearchKNN, linearSearchBest); // #define DFullSearch // comment/uncomment this line to set the search region #ifdef DFullSearch // Perform the inpainting (full search) InpaintingAlgorithm(graph, inpaintingVisitor, &boundaryNodeQueue, twoStepNearestNeighbor, &inpainter); #else NeighborhoodSearch<VertexDescriptorType, ImagePatchDescriptorMapType> neighborhoodSearch(originalImage->GetLargestPossibleRegion(), searchRadius, imagePatchDescriptorMap); // Perform the inpainting (local search) bool algorithmDebug = true; InpaintingAlgorithmWithLocalSearch(graph, inpaintingVisitor, &boundaryNodeQueue, twoStepNearestNeighbor, &inpainter, neighborhoodSearch, algorithmDebug); #endif }
int main(int argc, char *argv[]) { typedef itk::VectorImage<float, 2> ImageType; ImageType::Pointer image = ImageType::New(); Mask::Pointer mask = Mask::New(); typedef ImagePatchPixelDescriptor<ImageType> ImagePatchPixelDescriptorType; typedef FeatureVectorPixelDescriptor FeatureVectorPixelDescriptorType; // Create the graph typedef boost::grid_graph<2> VertexListGraphType; const unsigned int graphSize = 10; boost::array<std::size_t, 2> graphSideLengths = { { graphSize, graphSize } }; VertexListGraphType graph(graphSideLengths); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; IndexMapType indexMap(get(boost::vertex_index, graph)); // Create the priority map typedef boost::vector_property_map<float, IndexMapType> PriorityMapType; PriorityMapType priorityMap(num_vertices(graph), indexMap); // Create the node fill status map. Each pixel is either filled (true) or not filled (false). typedef boost::vector_property_map<bool, IndexMapType> FillStatusMapType; FillStatusMapType fillStatusMap(num_vertices(graph), indexMap); // Create the boundary status map. A node is on the current boundary if this property is true. // This property helps the boundaryNodeQueue because we can mark here if a node has become no longer // part of the boundary, so when the queue is popped we can check this property to see if it should // actually be processed. typedef boost::vector_property_map<bool, IndexMapType> BoundaryStatusMapType; BoundaryStatusMapType boundaryStatusMap(num_vertices(graph), indexMap); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<FeatureVectorPixelDescriptorType, IndexMapType> FeatureVectorDescriptorMapType; FeatureVectorDescriptorMapType featureVectorDescriptorMap(num_vertices(graph), indexMap); // Create the priority function typedef PriorityRandom PriorityType; PriorityType priorityFunction; // Create the boundary node queue. The priority of each node is used to order the queue. typedef boost::vector_property_map<std::size_t, IndexMapType> IndexInHeapMap; IndexInHeapMap index_in_heap(indexMap); // Create the priority compare functor typedef std::less<float> PriorityCompareType; PriorityCompareType lessThanFunctor; typedef boost::d_ary_heap_indirect<VertexDescriptorType, 4, IndexInHeapMap, PriorityMapType, PriorityCompareType> BoundaryNodeQueueType; BoundaryNodeQueueType boundaryNodeQueue(priorityMap, index_in_heap, lessThanFunctor); unsigned int patch_half_width = 10; vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New(); std::string featureName = "test"; typedef FeatureVectorPrecomputedPolyDataDescriptorVisitor<VertexListGraphType, FeatureVectorDescriptorMapType> FeatureVectorPrecomputedPolyDataDescriptorVisitorType; FeatureVectorPrecomputedPolyDataDescriptorVisitorType featureVectorPrecomputedPolyDataDescriptorVisitor(featureVectorDescriptorMap, polydata, featureName); typedef InpaintingVisitor<VertexListGraphType, ImageType, BoundaryNodeQueueType, FillStatusMapType, FeatureVectorPrecomputedPolyDataDescriptorVisitorType, PriorityType, PriorityMapType, BoundaryStatusMapType> InpaintingVisitorType; InpaintingVisitorType visitor(image, mask, boundaryNodeQueue, fillStatusMap, featureVectorPrecomputedPolyDataDescriptorVisitor, priorityMap, &priorityFunction, patch_half_width, boundaryStatusMap); return 0; }
// Run with: Data/trashcan.mha Data/trashcan_mask.mha 15 filled.mha int main(int argc, char *argv[]) { // Verify arguments if(argc != 5) { std::cerr << "Required arguments: image.mha imageMask.mha patchHalfWidth output.mha" << std::endl; std::cerr << "Input arguments: "; for(int i = 1; i < argc; ++i) { std::cerr << argv[i] << " "; } return EXIT_FAILURE; } // Setup the GUI system QApplication app( argc, argv ); // Parse arguments std::string imageFilename = argv[1]; std::string maskFilename = argv[2]; std::stringstream ssPatchRadius; ssPatchRadius << argv[3]; unsigned int patchHalfWidth = 0; ssPatchRadius >> patchHalfWidth; std::string outputFilename = argv[4]; // Output arguments std::cout << "Reading image: " << imageFilename << std::endl; std::cout << "Reading mask: " << maskFilename << std::endl; std::cout << "Patch half width: " << patchHalfWidth << std::endl; std::cout << "Output: " << outputFilename << std::endl; typedef FloatVectorImageType ImageType; typedef itk::ImageFileReader<ImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename); imageReader->Update(); ImageType* image = imageReader->GetOutput(); itk::ImageRegion<2> fullRegion = imageReader->GetOutput()->GetLargestPossibleRegion(); Mask::Pointer mask = Mask::New(); mask->Read(maskFilename); std::cout << "hole pixels: " << mask->CountHolePixels() << std::endl; std::cout << "valid pixels: " << mask->CountValidPixels() << std::endl; std::cout << "image has " << image->GetNumberOfComponentsPerPixel() << " components." << std::endl; typedef ImagePatchPixelDescriptor<ImageType> ImagePatchPixelDescriptorType; // Create the graph typedef boost::grid_graph<2> VertexListGraphType; boost::array<std::size_t, 2> graphSideLengths = { { fullRegion.GetSize()[0], fullRegion.GetSize()[1] } }; VertexListGraphType graph(graphSideLengths); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; IndexMapType indexMap(get(boost::vertex_index, graph)); // Create the priority map typedef boost::vector_property_map<float, IndexMapType> PriorityMapType; PriorityMapType priorityMap(num_vertices(graph), indexMap); // Create the boundary status map. A node is on the current boundary if this property is true. // This property helps the boundaryNodeQueue because we can mark here if a node has become no longer // part of the boundary, so when the queue is popped we can check this property to see if it should // actually be processed. typedef boost::vector_property_map<bool, IndexMapType> BoundaryStatusMapType; BoundaryStatusMapType boundaryStatusMap(num_vertices(graph), indexMap); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<ImagePatchPixelDescriptorType, IndexMapType> ImagePatchDescriptorMapType; ImagePatchDescriptorMapType imagePatchDescriptorMap(num_vertices(graph), indexMap); //ImagePatchDescriptorMapType smallImagePatchDescriptorMap(num_vertices(graph), indexMap); // Create the patch inpainter. The inpainter needs to know the status of each // pixel to determine if they should be inpainted. typedef MaskImagePatchInpainter InpainterType; MaskImagePatchInpainter patchInpainter(patchHalfWidth, mask); // Create the priority function // typedef PriorityRandom PriorityType; // PriorityType priorityFunction; typedef PriorityOnionPeel PriorityType; PriorityType priorityFunction(mask, patchHalfWidth); // Create the boundary node queue. The priority of each node is used to order the queue. typedef boost::vector_property_map<std::size_t, IndexMapType> IndexInHeapMap; IndexInHeapMap index_in_heap(indexMap); // Create the priority compare functor (we want the highest priority nodes to be first in the queue) typedef std::greater<float> PriorityCompareType; PriorityCompareType lessThanFunctor; typedef boost::d_ary_heap_indirect<VertexDescriptorType, 4, IndexInHeapMap, PriorityMapType, PriorityCompareType> BoundaryNodeQueueType; BoundaryNodeQueueType boundaryNodeQueue(priorityMap, index_in_heap, lessThanFunctor); // Create the descriptor visitor typedef ImagePatchDescriptorVisitor<VertexListGraphType, ImageType, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType; ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(image, mask, imagePatchDescriptorMap, patchHalfWidth); //ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(cielabImage, // mask, imagePatchDescriptorMap, patchHalfWidth); typedef ImagePatchDifference<ImagePatchPixelDescriptorType, SumAbsolutePixelDifference<ImageType::PixelType> > ImagePatchDifferenceType; ImagePatchDifferenceType imagePatchDifferenceFunction; // typedef WeightedSumAbsolutePixelDifference<ImageType::PixelType> PixelDifferenceFunctorType; // PixelDifferenceFunctorType pixelDifferenceFunctor; // std::vector<float> weights; // weights.push_back(1.0f); // weights.push_back(1.0f); // weights.push_back(1.0f); // float gradientWeight = 500.0f; // weights.push_back(gradientWeight); // weights.push_back(gradientWeight); // pixelDifferenceFunctor.Weights = weights; // std::cout << "Weights: "; // OutputHelpers::OutputVector(pixelDifferenceFunctor.Weights); // typedef ImagePatchDifference<ImagePatchPixelDescriptorType, PixelDifferenceFunctorType > // ImagePatchDifferenceType; // // ImagePatchDifferenceType imagePatchDifferenceFunction(pixelDifferenceFunctor); typedef CompositeDescriptorVisitor<VertexListGraphType> CompositeDescriptorVisitorType; CompositeDescriptorVisitorType compositeDescriptorVisitor; compositeDescriptorVisitor.AddVisitor(&imagePatchDescriptorVisitor); typedef CompositeAcceptanceVisitor<VertexListGraphType> CompositeAcceptanceVisitorType; CompositeAcceptanceVisitorType compositeAcceptanceVisitor; typedef InpaintingVisitor<VertexListGraphType, ImageType, BoundaryNodeQueueType, CompositeDescriptorVisitorType, CompositeAcceptanceVisitorType, PriorityType, PriorityMapType, BoundaryStatusMapType> InpaintingVisitorType; InpaintingVisitorType inpaintingVisitor(image, mask, boundaryNodeQueue, compositeDescriptorVisitor, compositeAcceptanceVisitor, priorityMap, &priorityFunction, patchHalfWidth, boundaryStatusMap, outputFilename); typedef DisplayVisitor<VertexListGraphType, ImageType> DisplayVisitorType; DisplayVisitorType displayVisitor(image, mask, patchHalfWidth); typedef DebugVisitor<VertexListGraphType, ImageType, BoundaryStatusMapType, BoundaryNodeQueueType> DebugVisitorType; DebugVisitorType debugVisitor(image, mask, patchHalfWidth, boundaryStatusMap, boundaryNodeQueue); LoggerVisitor<VertexListGraphType> loggerVisitor("log.txt"); PaintPatchVisitor<VertexListGraphType, ImageType> inpaintRGBVisitor(image, mask.GetPointer(), patchHalfWidth); typedef CompositeInpaintingVisitor<VertexListGraphType> CompositeInpaintingVisitorType; CompositeInpaintingVisitorType compositeInpaintingVisitor; compositeInpaintingVisitor.AddVisitor(&inpaintingVisitor); //compositeInpaintingVisitor.AddVisitor(&inpaintRGBVisitor); compositeInpaintingVisitor.AddVisitor(&displayVisitor); compositeInpaintingVisitor.AddVisitor(&debugVisitor); //compositeInpaintingVisitor.AddVisitor(&loggerVisitor); InitializePriority(mask, boundaryNodeQueue, priorityMap, &priorityFunction, boundaryStatusMap); // Initialize the boundary node queue from the user provided mask image. InitializeFromMaskImage<CompositeInpaintingVisitorType, VertexDescriptorType>(mask, &compositeInpaintingVisitor); // Create the nearest neighbor finders typedef LinearSearchKNNProperty<ImagePatchDescriptorMapType, ImagePatchDifferenceType > KNNSearchType; KNNSearchType knnSearch(imagePatchDescriptorMap, 50000, 1, imagePatchDifferenceFunction); // For debugging we use LinearSearchBestProperty instead of DefaultSearchBest // because it can output the difference value. typedef LinearSearchBestProperty<ImagePatchDescriptorMapType, ImagePatchDifferenceType > BestSearchType; BestSearchType bestSearch(imagePatchDescriptorMap, imagePatchDifferenceFunction); BasicViewerWidget<ImageType> basicViewerWidget(image, mask); basicViewerWidget.show(); // These connections are Qt::BlockingQueuedConnection because the algorithm quickly // goes on to fill the hole, and since we are sharing the image memory, we want to make sure these things are // refreshed at the right time, not after the hole has already been filled // (this actually happens, it is not just a theoretical thing). QObject::connect(&displayVisitor, SIGNAL(signal_RefreshImage()), &basicViewerWidget, SLOT(slot_UpdateImage()), Qt::BlockingQueuedConnection); QObject::connect(&displayVisitor, SIGNAL(signal_RefreshSource(const itk::ImageRegion<2>&, const itk::ImageRegion<2>&)), &basicViewerWidget, SLOT(slot_UpdateSource(const itk::ImageRegion<2>&, const itk::ImageRegion<2>&)), Qt::BlockingQueuedConnection); QObject::connect(&displayVisitor, SIGNAL(signal_RefreshTarget(const itk::ImageRegion<2>&)), &basicViewerWidget, SLOT(slot_UpdateTarget(const itk::ImageRegion<2>&)), Qt::BlockingQueuedConnection); QObject::connect(&displayVisitor, SIGNAL(signal_RefreshResult(const itk::ImageRegion<2>&, const itk::ImageRegion<2>&)), &basicViewerWidget, SLOT(slot_UpdateResult(const itk::ImageRegion<2>&, const itk::ImageRegion<2>&)), Qt::BlockingQueuedConnection); // TopPatchesDialog<ImageType> topPatchesDialog(image, mask, patchHalfWidth, &basicViewerWidget); // typedef VisualSelectionBest<ImageType> ManualSearchType; // ManualSearchType manualSearchBest(image, mask, patchHalfWidth, &topPatchesDialog); typedef DefaultSearchBest ManualSearchType; DefaultSearchBest manualSearchBest; // By specifying the radius as the image size/8, we are searching up to 1/4 of the image each time typedef NeighborhoodSearch<VertexDescriptorType> NeighborhoodSearchType; NeighborhoodSearchType neighborhoodSearch(fullRegion, fullRegion.GetSize()[0]/8); // Run the remaining inpainting QtConcurrent::run(boost::bind(InpaintingAlgorithmWithLocalSearch< VertexListGraphType, CompositeInpaintingVisitorType, BoundaryStatusMapType, BoundaryNodeQueueType, NeighborhoodSearchType, KNNSearchType, BestSearchType, ManualSearchType, InpainterType>, graph, compositeInpaintingVisitor, &boundaryStatusMap, &boundaryNodeQueue, neighborhoodSearch, knnSearch, bestSearch, boost::ref(manualSearchBest), patchInpainter)); return app.exec(); }
main(int argc, char *argv[]){ FILE *fp; gdImagePtr im, im2; int i,x,y,xsize,ysize,c; if(argc<7){ fprintf(stderr, "[%s] compiled [%s/%s]\n", argv[0], __DATE__, __TIME__); fprintf(stderr, "Usage : %s x1 x2 y1 y2 in-gif out-gif [-blue]\n", argv[0]); exit(1); } if(argc>7){ if(strcmp(argv[7], "-blue")==0) blueMode = 1; } x1 = atoi(argv[1]); x2 = atoi(argv[2]); y1 = atoi(argv[3]); y2 = atoi(argv[4]); infile = argv[5]; outfile = argv[6]; fp = fopen(infile, "rb"); if(!fp){ fprintf(stderr, "Can't open [%s]\n", infile); exit(1); } im = gdImageCreateFromGif(fp); fclose(fp); xsize = gdImageSX(im); ysize = gdImageSY(im); im2 = gdImageCreate(xsize, ysize); if(blueMode){ // use bluish gradation for low index value int j; for(i=0; i<256; i++){ j = (i-blueValue)*255/(255-blueValue); //////////////// blueValue --> 0, 255 --> 255 j = (j<0)?0:j; j= (j>255)?255:j; gdImageColorAllocate(im2, j, j, i); } } else { for(i=0; i<256; i++) gdImageColorAllocate(im2, i, i, i); } for(y=0; y<ysize; y++){ for(x=0; x<xsize; x++){ c = gdImageGetPixel(im, x, y); { int r,g,b; // fixed 2001.07.09 r = gdImageRed(im, c); g = gdImageGreen(im, c); b = gdImageBlue(im, c); c = ( g + g + r + b )/4; } indexMap(&c); gdImageSetPixel(im2, x, y, c); } } gdImageDestroy(im); fp = fopen(outfile, "wb"); if(!fp){ fprintf(stderr, "Can't open [%s]\n", outfile); exit(1); } gdImageGif(im2, fp); fclose(fp); }