seung-lab / euclidean-distance-transform-3d

Euclidean distance & signed distance transform for multi-label 3D anisotropic images using marching parabolas.
GNU General Public License v3.0
234 stars 37 forks source link

wrong results for non-c-contiguous arrays #18

Closed maweigert closed 4 years ago

maweigert commented 4 years ago

Hi,

For non-c-contiguous input arrays (such as transposed views etc) edt gives wrong results, e.g consider the following snippet:

import numpy as np
from edt import edt

# define mask (non contiguousarray)
x = np.zeros((128,128), np.uint16)
x[10:40,40:90] = 1
mask = x.T

print(mask.flags)

# show the problem 
import matplotlib.pyplot as plt
plt.figure(num=1)
for i,expr in enumerate(("mask",
                      "edt(mask)",
                      "edt(np.ascontiguousarray(mask))")):
    img = eval(expr)
    plt.subplot(1,3,i+1);
    plt.imshow(img);
    plt.title(expr, fontsize=8);
    plt.axis("off")
plt.show()

results in

Screenshot 2019-12-29 at 12 51 06

I assume this is similar to #10, where the fix was to check whether the input is either c or f contiguous (although it should be c contiguous?). I suspect wrapping everything in data = np.ascontiguousarray(data) should resolve this?

william-silversmith commented 4 years ago

edt was actually designed for Fortran order arrays and you can pass it order='F' but automatic detection would be better.

On Sun, Dec 29, 2019, 6:57 AM Martin Weigert notifications@github.com wrote:

Hi,

For non-c-contiguous input arrays (such as transposed views etc) edt gives wrong results, e.g consider the following snippet:

import numpy as npfrom edt import edt

define mask (non contiguousarray)

x = np.zeros((128,128), np.uint16) x[10:40,40:90] = 1 mask = x.T print(mask.flags)

show the problem import matplotlib.pyplot as plt

plt.figure(num=1)for i,expr in enumerate(("mask", "edt(mask)", "edt(np.ascontiguousarray(mask))")): img = eval(expr) plt.subplot(1,3,i+1); plt.imshow(img); plt.title(expr, fontsize=8); plt.axis("off") plt.show()

results in [image: Screenshot 2019-12-29 at 12 51 06] https://user-images.githubusercontent.com/11042162/71556515-e6afba00-2a39-11ea-98ad-dfea42ac7e45.png

I assume this is similar to #10 https://github.com/seung-lab/euclidean-distance-transform-3d/issues/10, where the fix https://github.com/seung-lab/euclidean-distance-transform-3d/blob/master/python/edt.pyx#L102 was to check whether the input is either c or f contiguous (although it should be c contiguous?). I suspect wrapping everything in data = np.ascontiguousarray(data) should resolve this?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/seung-lab/euclidean-distance-transform-3d/issues/18?email_source=notifications&email_token=AATGQSKEES57EDDWXS54KHLQ3CGC5A5CNFSM4KA3ICC2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4IDDE2TA, or unsubscribe https://github.com/notifications/unsubscribe-auth/AATGQSIEG7VBJ7F23ZJ3HCTQ3CGC5ANCNFSM4KA3ICCQ .

maweigert commented 4 years ago

edt was actually designed for Fortran order arrays

Sure, but the current default is order='C', so i guess that is a bit confusing ;) Btw, I just made a short PR (#19) that should fix that issue.

maweigert commented 4 years ago

Fixed with #22