void Vector()
{
  std::cout << "Vector()" << std::endl;
  
  std::vector<float> vec(patchRadius*patchRadius);

  ImageType::Pointer image = ImageType::New();
  CreateImage(image);

  itk::Index<2> center = {{imageSize/2, imageSize/2}};
  itk::ImageRegion<2> centerRegion = GetRegionInRadiusAroundPixel(center, patchRadius);
  std::vector<float> centerDescriptor = MakeDescriptor(centerRegion, image);

  std::vector<std::vector<float> > allDescriptors;

  {
  itk::ImageRegionIterator<ImageType> imageIterator(image, image->GetLargestPossibleRegion());

  while(!imageIterator.IsAtEnd())
    {
    itk::ImageRegion<2> region = GetRegionInRadiusAroundPixel(imageIterator.GetIndex(), patchRadius);
    if(image->GetLargestPossibleRegion().IsInside(region))
      {
      allDescriptors.push_back(MakeDescriptor(region, image));
      }

    ++imageIterator;
    }
  }

  std::cout << "There are " << allDescriptors.size() << " descriptors." << std::endl;
  std::cout << "There are " << allDescriptors[0].size() << " elements per descriptor." << std::endl;
  itk::TimeProbe clock1;

  clock1.Start();
  float totalDifference = 0.0f;
  for(unsigned int outerLoop = 0; outerLoop < numberOfOuterLoops; ++outerLoop)
    {
    for(unsigned int i = 0; i < allDescriptors.size(); ++i)
      {
      totalDifference += Difference(centerDescriptor, allDescriptors[i]);
      }
    }

  clock1.Stop();
  std::cout << "Total time: " << clock1.GetTotal() << std::endl;
  std::cout << "Total difference: " << totalDifference << std::endl;
}
void ITKImage()
{
  std::cout << "ITKImage()" << std::endl;
  
  ImageType::Pointer image = ImageType::New();
  CreateImage(image);

  itk::Index<2> center = {{imageSize/2, imageSize/2}};
  itk::ImageRegion<2> centerRegion = GetRegionInRadiusAroundPixel(center, patchRadius);

  std::vector<itk::ImageRegion<2> > allRegions;

  {
  itk::ImageRegionIterator<ImageType> imageIterator(image, image->GetLargestPossibleRegion());

  while(!imageIterator.IsAtEnd())
    {
    itk::ImageRegion<2> region = GetRegionInRadiusAroundPixel(imageIterator.GetIndex(), patchRadius);
    if(image->GetLargestPossibleRegion().IsInside(region))
      {
      allRegions.push_back(region);
      }
    ++imageIterator;
    }
  }

  itk::TimeProbe clock1;

  clock1.Start();

  float totalDifference = 0.0f;
  for(unsigned int outerLoop = 0; outerLoop < numberOfOuterLoops; ++outerLoop)
    {
    for(size_t regionId = 0; regionId < allRegions.size(); ++regionId)
      {
      totalDifference += Difference(allRegions[regionId], centerRegion, image);
      }
    }

  clock1.Stop();
  std::cout << "Total time: " << clock1.GetTotal() << std::endl;
  std::cout << "Total difference: " << totalDifference << std::endl;
  
}
itk::ImageRegion<2> Mask::FindFirstValidPatch(const unsigned int patchRadius)
{
  itk::ImageRegionConstIteratorWithIndex<Mask>
      maskIterator(this, this->GetLargestPossibleRegion());

  while(!maskIterator.IsAtEnd())
  {
    itk::ImageRegion<2> region =
        GetRegionInRadiusAroundPixel(maskIterator.GetIndex(), patchRadius);

    if(this->IsValid(region))
    {
      return region;
    }

    ++maskIterator;
  }

  throw std::runtime_error("No valid patches found!");
}
unsigned int Mask::CountValidPatches(const unsigned int patchRadius) const
{

  itk::ImageRegionConstIteratorWithIndex<Mask> maskIterator(this, this->GetLargestPossibleRegion());

  unsigned int counter = 0;
  // std::cout << "CountValidPatches (patch radius " << patchRadius << ")..." << std::endl;
  while(!maskIterator.IsAtEnd())
  {
    itk::ImageRegion<2> region =
        GetRegionInRadiusAroundPixel(maskIterator.GetIndex(), patchRadius);

    if(this->IsValid(region))
    {
      counter++;
    }
    ++maskIterator;
  }

  //std::cout << "There were " << counter << " valid patches." << std::endl;
  return counter;
}
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;
}