void initialize_vertex(VertexDescriptorType v, TGraph& g) const
  {
    //std::cout << "Initializing " << v[0] << " " << v[1] << std::endl;
    // Create the patch object and associate with the node
    itk::Index<2> index;
    index[0] = v[0];
    index[1] = v[1];

    itk::ImageRegion<2> region = ITKHelpers::GetRegionInRadiusAroundPixel(index, HalfWidth);

    unsigned int numberOfValues = Image->GetNumberOfComponentsPerPixel() * region.GetNumberOfPixels();
    if(MaskImage->IsValid(region))
      {
      std::vector<float> pixels(numberOfValues, 0);
      itk::ImageRegionIterator<TImage> imageIterator(Image, region);
 
      unsigned int pixelCounter = 0;
      while(!imageIterator.IsAtEnd())
        {
        TImage::PixelType p = imageIterator.Get();
        for(unsigned int component = 0; component < p.Size(); ++component)
          {
          pixels[Image->GetNumberOfComponentsPerPixel() * pixelCounter + component] = p[component];
          }
        pixelCounter++;
        ++imageIterator;
        }
      FeatureVectorPixelDescriptor descriptor(this->image, this->mask, region);
      descriptor.SetVertex(v);
      put(DescriptorMap, v, descriptor);
      }
    else
      {
      FeatureVectorPixelDescriptor descriptor(numberOfValues);
      descriptor.SetVertex(v);
      put(DescriptorMap, v, descriptor);
      }

  };
  void FinishVertex(VertexDescriptorType target, VertexDescriptorType sourceNode)
  {
    //OutputHelpers::WriteImage(MaskImage, Helpers::GetSequentialFileName("mask", this->NumberOfFinishedVertices, "png"));
    ITKHelpers::WriteImage(MaskImage, Helpers::GetSequentialFileName("mask",
                                                                        this->NumberOfFinishedVertices, "mha"));
    //OutputHelpers::WriteVectorImageAsRGB(Image, Helpers::GetSequentialFileName("output", this->NumberOfFinishedVertices, "png"));
    ITKHelpers::WriteImage(Image, Helpers::GetSequentialFileName("output",
                                                                    this->NumberOfFinishedVertices, "mha"));

    ITKHelpers::WriteRGBImage(Image, Helpers::GetSequentialFileName("output",
                                                                    this->NumberOfFinishedVertices, "png"));

    typename TImage::PixelType holeColor;
    holeColor.SetSize(Image->GetNumberOfComponentsPerPixel());
    holeColor[0] = 255;
    holeColor[1] = 0;
    holeColor[2] = 0;

    MaskOperations::WriteMaskedRegionPNG(Image, MaskImage, Image->GetLargestPossibleRegion(), Helpers::GetSequentialFileName("maskedOutput", this->NumberOfFinishedVertices, "png"),
                       holeColor);


    typedef itk::Image<unsigned char, 2> IndicatorImageType;

    IndicatorImageType::Pointer boundaryStatusMapImage = IndicatorImageType::New();
    boundaryStatusMapImage->SetRegions(Image->GetLargestPossibleRegion());
    boundaryStatusMapImage->Allocate();
//     BoostHelpers::WritePropertyMapAsImage(BoundaryStatusMap, boundaryStatusMapImage.GetPointer(),
//                                           Helpers::GetSequentialFileName("boundaryStatusMap",
//                                           this->NumberOfFinishedVertices, "png"));

    IndicatorImageType::Pointer validBoundaryNodeImage = IndicatorImageType::New();
    validBoundaryNodeImage->SetRegions(Image->GetLargestPossibleRegion());
    validBoundaryNodeImage->Allocate();
//     BoostHelpers::WriteValidQueueNodesAsImage(BoundaryNodeQueue, BoundaryStatusMap,
//                                                 validBoundaryNodeImage.GetPointer(),
//                                           Helpers::GetSequentialFileName("boundaryQueueValidNodes",
//                                                this->NumberOfFinishedVertices, "png"));

    IndicatorImageType::Pointer allBoundaryNodeImage = IndicatorImageType::New();
    allBoundaryNodeImage->SetRegions(Image->GetLargestPossibleRegion());
    allBoundaryNodeImage->Allocate();
//     BoostHelpers::WriteAllQueueNodesAsImage(BoundaryNodeQueue, allBoundaryNodeImage.GetPointer(),
//                                           Helpers::GetSequentialFileName("boundaryQueueAllNodes",
//                                            this->NumberOfFinishedVertices, "png"));

    this->NumberOfFinishedVertices++;

    // std::cout << "Finished node " << this->NumberOfFinishedVertices << std::endl;

  }
  void PotentialMatchMade(VertexDescriptorType targetNode, VertexDescriptorType sourceNode)
  {
    std::cout << "Match made: target: " << targetNode[0] << " " << targetNode[1]
              << " with source: " << sourceNode[0] << " " << sourceNode[1] << std::endl;
  std::cout << "Writing pair " << NumberOfFinishedVertices << std::endl;
  
    {
    itk::Index<2> sourceIndex = ITKHelpers::CreateIndex(sourceNode);

    itk::ImageRegion<2> sourceRegion = ITKHelpers::GetRegionInRadiusAroundPixel(sourceIndex, this->HalfWidth);

    ITKHelpers::WriteVectorImageRegionAsRGB(Image, sourceRegion,
                                               Helpers::GetSequentialFileName("sourcePatch",
                                                                              this->NumberOfFinishedVertices, "png"));
    }

    {
    // Construct the region around the vertex
    itk::Index<2> indexToFinish = ITKHelpers::CreateIndex(targetNode);

    itk::ImageRegion<2> region = ITKHelpers::GetRegionInRadiusAroundPixel(indexToFinish, this->HalfWidth);

    ITKHelpers::WriteVectorImageRegionAsRGB(Image, region,
                                               Helpers::GetSequentialFileName("targetPatch",
                                                                              this->NumberOfFinishedVertices, "png"));
    ITKHelpers::WriteRegionAsRGBImage(this->MaskImage, region,
                               Helpers::GetSequentialFileName("maskPatch", this->NumberOfFinishedVertices, "png"));


    typename TImage::PixelType holeColor;
    holeColor.SetSize(Image->GetNumberOfComponentsPerPixel());
    holeColor[0] = 255;
    holeColor[1] = 0;
    holeColor[2] = 0;
    MaskOperations::WriteMaskedRegionPNG(this->Image, this->MaskImage, region,
                                         Helpers::GetSequentialFileName("maskedTargetPatch", this->NumberOfFinishedVertices, "png"),
                       holeColor);
    }
  }
  bool AcceptMatch(VertexDescriptorType target, VertexDescriptorType source, float& computedEnergy) const
  {
    itk::Index<2> targetPixel = ITKHelpers::CreateIndex(target);
    itk::ImageRegion<2> targetRegion = ITKHelpers::GetRegionInRadiusAroundPixel(targetPixel, HalfWidth);

    itk::Index<2> sourcePixel = ITKHelpers::CreateIndex(source);
    itk::ImageRegion<2> sourceRegion = ITKHelpers::GetRegionInRadiusAroundPixel(sourcePixel, HalfWidth);

    // Get the pixels to use in the target region
    std::vector<typename TImage::PixelType> validPixelsTargetRegion =
             MaskOperations::GetValidPixelsInRegion(Image, MaskImage, targetRegion);

    // Get the pixels to use in the source region
    std::vector<itk::Offset<2> > validOffsets = MaskImage->GetValidOffsetsInRegion(targetRegion);
    std::vector<itk::Index<2> > sourcePatchValidPixelIndices =
           ITKHelpers::OffsetsToIndices(validOffsets, sourceRegion.GetIndex());
    std::vector<typename TImage::PixelType> validPixelsSourceRegion =
           ITKHelpers::GetPixelValues(Image, sourcePatchValidPixelIndices);

    assert(validPixelsSourceRegion.size() == validPixelsTargetRegion.size());

    unsigned int numberOfPixels = validPixelsTargetRegion.size();

    float totalHistogramDifference = 0.0f;

    for(unsigned int component = 0; component < Image->GetNumberOfComponentsPerPixel(); ++component)
    {
      std::vector<float> targetValues(numberOfPixels);
      std::vector<float> sourceValues(numberOfPixels);

      for(unsigned int pixelId = 0; pixelId < numberOfPixels; ++pixelId)
      {
        targetValues[pixelId] = validPixelsTargetRegion[pixelId][component];
        sourceValues[pixelId] = validPixelsSourceRegion[pixelId][component];
      }

      float minTargetValue = *(std::min_element(targetValues.begin(), targetValues.end()));
      float minSourceValue = *(std::min_element(sourceValues.begin(), sourceValues.end()));
      
      float maxTargetValue = *(std::max_element(targetValues.begin(), targetValues.end()));
      float maxSourceValue = *(std::max_element(sourceValues.begin(), sourceValues.end()));

      float minValue = std::min(minTargetValue, minSourceValue);
      float maxValue = std::max(maxTargetValue, maxSourceValue);
      
      std::vector<float> targetHistogram = Histogram::ScalarHistogram(targetValues, 20,
                                                                      minValue, maxValue);
      std::vector<float> sourceHistogram = Histogram::ScalarHistogram(sourceValues, 20,
                                                                      minValue, maxValue);

      // We normalize the histograms because the magnitude of the histogram difference should not
      // change based on the number of pixels that were in the valid region of the patches.
      Helpers::NormalizeVector(targetHistogram);
      Helpers::NormalizeVector(sourceHistogram);

      float channelHistogramDifference = Helpers::VectorSumOfAbsoluteDifferences(targetHistogram, sourceHistogram);
      totalHistogramDifference += channelHistogramDifference;
    }

    // Compute the difference
    computedEnergy = totalHistogramDifference;
    std::cout << "HistogramDifferenceAcceptanceVisitor Energy: " << computedEnergy << std::endl;

    if(computedEnergy < DifferenceThreshold)
      {
      std::cout << "HistogramDifferenceAcceptanceVisitor: Match accepted (less than " << DifferenceThreshold
                << ")" << std::endl;
      return true;
      }
    else
      {
      std::cout << "HistogramDifferenceAcceptanceVisitor: Match rejected (greater than " << DifferenceThreshold
                << ")" << std::endl;
      return false;
      }
  };
  bool AcceptMatch(VertexDescriptorType target, VertexDescriptorType source, float& computedEnergy) const
  {
    itk::Index<2> targetPixel = ITKHelpers::CreateIndex(target);
    itk::ImageRegion<2> targetRegion = ITKHelpers::GetRegionInRadiusAroundPixel(targetPixel, HalfWidth);

    itk::Index<2> sourcePixel = ITKHelpers::CreateIndex(source);
    itk::ImageRegion<2> sourceRegion = ITKHelpers::GetRegionInRadiusAroundPixel(sourcePixel, HalfWidth);

    // Compute the average of the valid pixels in the target region
    std::vector<typename TImage::PixelType> targetRegionPixels = MaskOperations::GetValidPixelsInRegion(Image, MaskImage, targetRegion);

    // The next line is the only thing that changed versus HistogramDifferenceAcceptanceVisitor
    std::vector<itk::Offset<2> > targetRegionHoleOffsets = MaskImage->GetHoleOffsetsInRegion(targetRegion);
    std::vector<itk::Index<2> > sourcePatchPixelIndices = ITKHelpers::OffsetsToIndices(targetRegionHoleOffsets, sourceRegion.GetIndex());
    std::vector<typename TImage::PixelType> sourceRegionPixels = ITKHelpers::GetPixelValues(Image, sourcePatchPixelIndices);

    assert(sourceRegionPixels.size() == targetRegionPixels.size());

    float totalHistogramDifference = 0.0f;

    for(unsigned int component = 0; component < Image->GetNumberOfComponentsPerPixel(); ++component)
    {
      std::vector<float> targetValues(targetRegionPixels.size());
      std::vector<float> sourceValues(sourceRegionPixels.size());

      for(unsigned int pixelId = 0; pixelId < targetRegionPixels.size(); ++pixelId)
      {
        targetValues[pixelId] = targetRegionPixels[pixelId][component];
      }

      for(unsigned int pixelId = 0; pixelId < sourceRegionPixels.size(); ++pixelId)
      {
        sourceValues[pixelId] = sourceRegionPixels[pixelId][component];
      }

      std::vector<float> targetHistogram = Histogram<int>::ScalarHistogram(targetValues, 20, Mins[component], Maxs[component]);
      std::vector<float> sourceHistogram = Histogram<int>::ScalarHistogram(sourceValues, 20, Mins[component], Maxs[component]);

      // We normalize the histograms because the magnitude of the histogram difference should not change based on the number of pixels that were in the valid region of the patches.
      Helpers::NormalizeVector(targetHistogram);
      Helpers::NormalizeVector(sourceHistogram);

      float channelHistogramDifference = Helpers::VectorSumOfAbsoluteDifferences(targetHistogram, sourceHistogram);
      totalHistogramDifference += channelHistogramDifference;
    }

    // Compute the difference
    computedEnergy = totalHistogramDifference;
    std::cout << "HoleHistogramDifferenceAcceptanceVisitor Energy: " << computedEnergy << std::endl;

    if(computedEnergy < DifferenceThreshold)
      {
      std::cout << "HoleHistogramDifferenceAcceptanceVisitor: Match accepted (less than " << DifferenceThreshold << ")" << std::endl;
      return true;
      }
    else
      {
      std::cout << "HoleHistogramDifferenceAcceptanceVisitor: Match rejected (greater than " << DifferenceThreshold << ")" << std::endl;
      return false;
      }
  };