# Comparing ITK images efficiently.

**URL:** https://discourse.itk.org/t/comparing-itk-images-efficiently/5203
**Category:** Beginner Questions
**Created:** [July 20, 2022, 1:07pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203 "2022-07-20T13:07:36Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Seun](https://discourse.itk.org/user_avatar/discourse.itk.org/seun/32/2857_2.png) [@Seun](https://discourse.itk.org/u/Seun)
#### Post date: [July 20, 2022, 1:07pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/1 "2022-07-20T13:07:36Z")

</div>

Hello everyone,

I was wondering what would be the fastest way in comparing 2 ITK images irrespective of how large the images are. For instance if I have 2 images both 1000x1000 and I would like to make sure they are exactly the same, would it be naive to do such thing as depicted below where I get the region for both images and manually check each pixel?

```auto
// 'InputPixelType' -> is just a template for the primitive type ie: int32_t, double, float et al.
// both readers are just
// typename itk::ImageSeriesReader<itk::Image<InputPixelType, kDimension>>::Pointer
// kDimension = 3 (defined in my code)

typename itk::Image<InputPixelType, kDimension>::Pointer image = reader->GetOutput();
typename itk::Image<InputPixelType, kDimension>::Pointer image2 = reader2->GetOutput();

// then I basically check both their spacings, origins and sizes (code omitted here). 
// and Finally I do something like this

typedef itk::ImageRegionConstIterator<itk::Image<InputPixelType, kDimension>> ConstIter;
							
ConstIter iter1(image, image->GetRequestedRegion());
ConstIter iter2(image2, image2->GetRequestedRegion());
							
for (iter1.GoToBegin(), iter2.GoToBegin(); !iter1.IsAtEnd(); ++iter1, ++iter2)
{
       // IsAlmostEqual -> custom function to compare using a fudge factor
       if(!IsAlmostEqual(iter1.Value(), iter2.Value(), DBL_EPSILON))
	   {
           // boolean success to indicate failure.
		  success = false;
		  break;
	   }
}

```

> If so could someone point me in the right direction as to the best way to approach this issue. I have had a look at ‘InsightSoftwareGuide-Book1-5.0.0’ but couldn’t figure out the best approach. Thanks

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [July 20, 2022, 1:20pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/2 "2022-07-20T13:20:50Z")

</div>

You should also check their directions. Other than that, you code looks fine. Optionally [parallelize](https://examples.itk.org/src/core/common/useparallelizeimageregion/documentation) your code.

You could also use [itk::Testing::ComparisonImageFilter](https://itk.org/Doxygen/html/classitk_1_1Testing_1_1ComparisonImageFilter.html).

---

<div class="post-metadata">

### Author: ![Seun](https://discourse.itk.org/user_avatar/discourse.itk.org/seun/32/2857_2.png) [@Seun](https://discourse.itk.org/u/Seun)
#### Post date: [July 20, 2022, 1:29pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/3 "2022-07-20T13:29:49Z")

</div>

Hello [Dženan](https://discourse.itk.org/u/dzenanz),

Thanks for the expeditious response. Is it safe to assume that ‘itk::Testing::ComparisonImageFilter’ is just another approach to my code above and it wouldn’t necessarily be any faster? It seems to me parallelization will produce faster comparisons. Oh and thanks for highlighting ‘checking the directions’ of both images (I’m actually doing so in my code but forgot to put it as part of my comment above) Thanks.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [July 20, 2022, 1:39pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/4 "2022-07-20T13:39:33Z")

</div>

`ComparisonImageFilter` is [multi-threaded](https://github.com/InsightSoftwareConsortium/ITK/blob/v5.3rc04/Modules/Core/TestKernel/include/itkTestingComparisonImageFilter.hxx#L106). You should set [tolerance](https://github.com/InsightSoftwareConsortium/ITK/blob/v5.3rc04/Modules/Core/TestKernel/include/itkTestingComparisonImageFilter.hxx#L36) above zero for float images.

---

<div class="post-metadata">

### Author: ![Seun](https://discourse.itk.org/user_avatar/discourse.itk.org/seun/32/2857_2.png) [@Seun](https://discourse.itk.org/u/Seun)
#### Post date: [July 20, 2022, 1:45pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/5 "2022-07-20T13:45:20Z")

</div>

Great, thanks a bunch. I’ll try your suggestions out and get back to you.

---

<div class="post-metadata">

### Author: ![Seun](https://discourse.itk.org/user_avatar/discourse.itk.org/seun/32/2857_2.png) [@Seun](https://discourse.itk.org/u/Seun)
#### Post date: [July 20, 2022, 7:49pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/6 "2022-07-20T19:49:42Z")

</div>

Hello [Dženan](https://discourse.itk.org/u/dzenanz)

So I was able to try the above suggested ideas and ‘itk::Testing::ComparisonImageFilter’ basically was slightly slower than my initial code (unless I’m doing something wrong)

```auto
// 'InputPixelType' -> is just a template for the primitive type ie: int32_t, double, float et al.
// both readers are just
// typename itk::ImageSeriesReader<itk::Image<InputPixelType, kDimension>>::Pointer
// kDimension = 3 (defined in my code)

using ImageType = itk::Image<InputPixelType, kDimension>;
using DiffType = itk::Testing::ComparisonImageFilter<ImageType, ImageType>;
							
typename DiffType::Pointer difference = DiffType::New();
difference->SetValidInput(image);
difference->SetTestInput(image2);
difference->SetDifferenceThreshold(DBL_EPSILON);
difference->SetToleranceRadius(0.1); // set above 0.1 for float 
difference->UpdateLargestPossibleRegion();
							
bool differenceFailed = false;
int numberOfPixelsTolerance = 5;
							
const double averageIntensityDifference = difference->GetTotalDifference();
							
const unsigned long numberOfPixelsWithDifferences = difference->GetNumberOfPixelsWithDifferences();
							
if (averageIntensityDifference > 0.0)
{
	if (static_cast<int>(numberOfPixelsWithDifferences) > numberOfPixelsTolerance)
	{
		differenceFailed = true;
	}
	else
	{
		differenceFailed = false;
	}
}
else
{
	differenceFailed = false;
}
							
if (differenceFailed)
{
	success = false;
}

```

whereas when I tried parallelizing it produced slightly faster than my initial code but not that impressive, I’m not sure if there are some settings that needs to be executed to reap the benefits of the MultiThreader. Parallelize code can be seen below.

```auto
// 'InputPixelType' -> is just a template for the primitive type ie: int32_t, double, float et al.
// both readers are just
// typename itk::ImageSeriesReader<itk::Image<InputPixelType, kDimension>>::Pointer
// kDimension = 3 (defined in my code)

itk::MultiThreaderBase::Pointer	multiThread = itk::MultiThreaderBase::New();
							
// Typically this is 16 by default.
//itk::ThreadIdType numGlobalThread = multiThread->GetGlobalDefaultNumberOfThreads();
itk::ThreadIdType maxGlobalThread = multiThread->GetGlobalMaximumNumberOfThreads();
							
// trying 'maxGlobalThread'
itk::ThreadIdType globalThreadsToUse = maxGlobalThread ; // numGlobalThread * 4;
globalThreadsToUse = (maxGlobalThread < globalThreadsToUse) ? maxGlobalThread - 2 : globalThreadsToUse;
							
std::cout << "\n\n\t # of Threads: " << globalThreadsToUse << "\n" << endl;
							
multiThread->SetGlobalDefaultNumberOfThreads(globalThreadsToUse);
							
using ImageType = itk::Image<InputPixelType, kDimension>;
							
auto compare = [&success, image, image2](const typename ImageType::RegionType& region) -> void
{
	// Check voxels to see if they match.
	typedef itk::ImageRegionConstIterator<ImageType> ConstIter;
	ConstIter iter1(image, region);
	ConstIter iter2(image2, region);
								
	for (; !iter1.IsAtEnd(); ++iter1, ++iter2)
	{
		if(!IsAlmostEqual(iter1.Value(), iter2.Value(), DBL_EPSILON))
		{
	        std::cout << "\n[Parallelizing]: In comparison (" << iter1.Value() << " is != " << iter2.Value() << ")" << std::endl;
			success = false;
			break;
		}
	}
								
	if (!success){
		return;
	}
};
							
multiThread->ParallelizeImageRegion<kDimension>(image->GetBufferedRegion(), compare, nullptr);

```

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [July 20, 2022, 8:02pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/7 "2022-07-20T20:02:13Z")

</div>

I guess the main conclusion here is that this problem is memory speed limited (usually called memory bound), not CPU bound, so it does not benefit a lot from parallelization.

`ComparisonImageFilter` does more things than your original code.

> [@Seun](#):
>
> `difference->SetToleranceRadius(0.1)`

This is what might be making it slower.

---

<div class="post-metadata">

### Author: ![Seun](https://discourse.itk.org/user_avatar/discourse.itk.org/seun/32/2857_2.png) [@Seun](https://discourse.itk.org/u/Seun)
#### Post date: [July 20, 2022, 8:04pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/8 "2022-07-20T20:04:43Z")

</div>

Thanks for the feedback, I did try just 0.0 as the tolerance default and it made no difference. I guess I’m not quite understanding what the tolerance does.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [July 20, 2022, 8:16pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/9 "2022-07-20T20:16:06Z")

</div>

`ToleranceRadius` allows to compare pixel’s value to neighboring pixels, within the radius. I guess this needs to be \>=1 to have an effect.

`ComparisonImageFilter` computes mean of the difference, so that might be the reason for running slower.

---

<div class="post-metadata">

### Author: ![Seun](https://discourse.itk.org/user_avatar/discourse.itk.org/seun/32/2857_2.png) [@Seun](https://discourse.itk.org/u/Seun)
#### Post date: [July 20, 2022, 8:27pm UTC](https://discourse.itk.org/t/comparing-itk-images-efficiently/5203/10 "2022-07-20T20:27:50Z")

</div>

Thanks a lot, I’ll keep that in mind and test with a tolerance larger than 1.0. Hopefully I’ll see better results.
