If I have a collection of images and I’d like to quickly check that they’re “overlapping”, that is, have the same origin, pixel dimensions and direction cosines, is there a filter/test which does this other than comparing the GetSpacing(), GetOrigin() and GetDirection() vectors directly?
Hello @gdevenyi,
Here’s what I do (it isn’t the nicest code in the world but maintains consistency with the internals of ITK/SimpleITK):
if not np.array_equal(np.array(image1.GetSize()), np.array(image2.GetSize())):
raise ValueError("Sizes don't match")
image1_proxy = image1[0:1,0:1,0:1]
image2_proxy = image2[0:1,0:1,0:1]
try: # comparison of origin, spacing and direction using ITK/SimpleITK epsilon
image1_proxy + image2_proxy
except Exception:
raise ValueError("Origin, spacing or direction do not match.")
Ha! That’s a very clever hack relying on the exception checks inside SimpleITK to achieve it.
I don’t think this will work out for me, as I want to avoid loading the image data as there could be a large number of high resolution images, and I need to test each one before I go downstream with my processing choices. Thanks for the suggestion!
Still doable if the file format supports streaming:
file_reader = sitk.ImageFileReader()
file_reader.SetFileName(file_name1)
file_reader.ReadImageInformation()
image1_size = np.array(file_reader.GetSize())
# read the first voxel to get the image's origin, spacing, direction cosine
file_reader.SetExtractIndex([0,0,0])
file_reader.SetExtractSize([1,1,1])
image1_proxy = file_reader.Execute()
If it doesn’t support streaming, then you’ll just have to read the image information and construct the “proxy” images from that information.
… and that might be more trouble than directly comparing size, spacing, origin and direction. Invoking code in ImageToImageFilter::VerifyInputInformation() is probably not feasible, but stealing code from it totally is
Since I’m already using numpy, I went with this test in my reader loop
if not (np.allclose(img.GetSpacing(), reader.GetSpacing(), atol=1e-6) and
np.allclose(img.GetOrigin(), reader.GetOrigin(), atol=1e-6) and
np.allclose(img.GetDirection(), reader.GetDirection())):
There are good reasons why ImageToImageFilter::VerifyInputInformation()
is so complex. The proposed simple check (based on a fixed absolute tolerance value) will cause trouble by either incorrectly rejecting some images that have actually matching geometries or not catching some actual mismatches.
The current ImageToImageFilter::VerifyInputInformation()
implementation should be exposed in Python, otherwise it would be very hard to ensure consistent behavior.