-
Notifications
You must be signed in to change notification settings - Fork 46
Description
I noticed that using the Python API can result in transposed output in some cases, causing issues in subsequent processing where the connected component output isn't aligned with the original input image. I suspect that it has to do with the way numpy arrays are stored in the memory. I think the issue is caused by Fortran memory ordering. With C ordered input arrays I didn't experience the transposed output issue. Even with Fortran ordering there need to be some specific conditions, as not all Fortran ordered inputs lead to the transposed output. A default C ordered numpy array can become "F" ordered by transposing it, but I loading an nrrd file using pynrrd can also result in "F" ordered numpy arrays. I'd recommend changing the code so that if a numpy array is passed as input, first it is checked and ensured to be "C" ordered . I managed to illustrate the issue with the following code, where without modifications the output is transposed compared to the input:
import numpy as np
import matplotlib.pyplot as plt
import cc3d
a = np.zeros((50, 50, 50), order="F") # the array can be "F" ordered if it's loaded using pynrrd
a.T[10:20, 20:30, 30:40] = 1
a[:20, :30, :40] = 2 # this and the above line are both needed to reproduce the issue
lbls_out, N_blobs = cc3d.largest_k(a, k=1, connectivity=6, return_N=True)
largest_cc = lbls_out.T == 1 # if lbls_out is transposed here, then the largest connected component is aligned with the input on the visualization below
fig, ax = plt.subplots(1, 2, figsize=(10, 5))
i = 5
ax[0].imshow(a[i])
ax[0].set_title("input")
ax[1].imshow(largest_cc[i])
ax[1].set_title("labels out")The input and the output can be aligned by:
- initializing the array with "C" ordering
- removing any of the two lines where values of the array are set to 1 or 2
- transposing lbls_out