loli / medpy

Medical image processing in Python
http://loli.github.io/medpy/
GNU General Public License v3.0
559 stars 136 forks source link

assd function crashes on different size arrays #131

Open BarY7 opened 3 months ago

BarY7 commented 3 months ago

Hello, first time using this lib, but I think a bug was introduced in the latest version from yesterday. We have in the assd function in metric/binary.py:

    assd = numpy.mean(
        (
            __surface_distances(result, reference, voxelspacing, connectivity),
            __surface_distances(reference, result, voxelspacing, connectivity),
        )
    )
    return assd

When the returning arrays are not of the same dim, numpy.mean crashes with the exception:

setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions.

A possible fix:

    assd = numpy.mean(
        (
            np.concatenate([__surface_distances(result, reference, voxelspacing, connectivity),
            __surface_distances(reference, result, voxelspacing, connectivity)])
        )
    )
    return assd
oskar-maier-ms commented 2 months ago

Hey BarY7, thanks for reporting! I'll take a look when I find some time and release another minor version.

oskar-maier-ms commented 2 months ago

Note: Error stems from __surface_distances(a) and __surface_distances(b) returning results of differing lengths.

iTomxy commented 1 month ago

+1. When using with numpy==1.24.3, I get:

Traceback (most recent call last):
  File "bone_eval.py", line 208, in <module>
    test_3d(args, model)
  File "/data/itom/miniconda3/envs/cu116_pt1131/lib/python3.8/site-packages/torch/autograd/grad_mode.py", line 27, in decorate_context
    return func(*args, **kwargs)
  File "bone_eval.py", line 159, in test_3d
    evaluator(pred_vol, label_vol)
  File "/data/itom/tyliang/codes/tmp.da-seg-bone/evaluation.py", line 107, in __call__
    a = fn(B_pred_c, B_c)
  File "/data/itom/miniconda3/envs/cu116_pt1131/lib/python3.8/site-packages/medpy/metric/binary.py", line 470, in assd
    assd = numpy.mean(
  File "<__array_function__ internals>", line 200, in mean
  File "/data/itom/miniconda3/envs/cu116_pt1131/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 3464, in mean
    return _methods._mean(a, axis=axis, dtype=dtype,
  File "/data/itom/miniconda3/envs/cu116_pt1131/lib/python3.8/site-packages/numpy/core/_methods.py", line 165, in _mean
    arr = asanyarray(a)
ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.

And when I downgrade numpy to 1.21.6 as suggested in [1], I get:

Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
Traceback (most recent call last):
  File "bone_eval.py", line 208, in <module>
    test_3d(args, model)
  File "/data/itom/miniconda3/envs/cu116_pt1131/lib/python3.8/site-packages/torch/autograd/grad_mode.py", line 27, in decorate_context
    return func(*args, **kwargs)
  File "bone_eval.py", line 159, in test_3d
    evaluator(pred_vol, label_vol)
  File "/data/itom/tyliang/codes/tmp.da-seg-bone/evaluation.py", line 107, in __call__
    a = fn(B_pred_c, B_c)
  File "/data/itom/miniconda3/envs/cu116_pt1131/lib/python3.8/site-packages/medpy/metric/binary.py", line 470, in assd
    assd = numpy.mean(
  File "<__array_function__ internals>", line 5, in mean
  File "/data/itom/miniconda3/envs/cu116_pt1131/lib/python3.8/site-packages/numpy/core/fromnumeric.py", line 3440, in mean
    return _methods._mean(a, axis=axis, dtype=dtype,
  File "/data/itom/miniconda3/envs/cu116_pt1131/lib/python3.8/site-packages/numpy/core/_methods.py", line 179, in _mean
    ret = umr_sum(arr, axis, dtype, out, keepdims, where=where)
ValueError: operands could not be broadcast together with shapes (148451,) (73048,)

As suggested in [1], it seems dtype="object" should be passed in line 470 of medpy/metric/binary.py in assd = numpy.mean(.


  1. setting an array element with a sequence requested array has an inhomogeneous shape after 1 dimensions The detected shape was (2,)+inhomogeneous part
STHxiao commented 2 weeks ago

I met the same problem when using with numpy==1.26.3

Savitar001 commented 1 week ago

I met the same problem when using with numpy==1.26.1,hope be solved