Home > OS >  ValueError: need at least one array to concatenate with upgraded Numpy
ValueError: need at least one array to concatenate with upgraded Numpy

Time:10-06

I'm bringing dependencies up to date in an old project of mine and recently ran into an issue when using RandomWalker as follows:

    import numpy as np
    from skimage import color as skc
    from skimage.segmentation import random_walker


    def my_func(img):
        img = skc.rgb2gray(img)

        markers = np.zeros_like(img, dtype=np.uint)
        markers[img < (img.mean() - img.std()) / 2.0] = 1
        markers[img > (img.mean()   img.std()) / 2.0] = 2

        try:
            rw = random_walker(img, markers) # ValueError: need at least one array to concatenate
        except RuntimeError:
            ...

The dependencies I previously got and that are currently working just fine are (if there is any other version required that can help troubleshooting just ask):

# Python 3.6
numpy==1.14.5
scikit-image==0.13.0
scikit-learn==0.19.2

And upgraded ones where the ValueError: need at least one array to concatenate is thrown are:

# Python 3.9
numpy==1.21.0
scikit-image==0.19.1
scikit-learn==1.1.2

Example for testing - install previously mentioned dependencies from requirements.txt, with the Python versions mentioned:

import numpy as np
from skimage.segmentation import random_walker
from skimage import color as skc


img_array = np.array(
    [
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
        [
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
            [255, 255, 255],
        ],
    ]
).astype(np.uint8)


def walker_texas_ranger():
    image = skc.rgb2gray(img_array)

    markers = np.zeros_like(image, dtype=np.uint)
    markers[image < image.mean() - image.std() / 2.0] = 1
    markers[image > image.mean()   image.std() / 2.0] = 2

    try:
        rw = random_walker(image, markers)
    except RuntimeError:
        return None

    return rw


if __name__ == '__main__':
    walker_texas_ranger()

Sample execution stack trace running latest dependencies with Python 3.9:

  File "/Users/me/examples/main.py", line 188, in walker_texas_ranger
    rw = random_walker(image, markers)
  File "/usr/local/lib/python3.9/site-packages/skimage/_shared/utils.py", line 338, in fixed_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/skimage/_shared/utils.py", line 293, in fixed_func
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/skimage/segmentation/random_walker_segmentation.py", line 490, in random_walker
    lap_sparse, B = _build_linear_system(data, spacing, labels, nlabels, mask,
  File "/usr/local/lib/python3.9/site-packages/skimage/segmentation/random_walker_segmentation.py", line 157, in _build_linear_system
    seeds_mask = sparse.csc_matrix(np.hstack(
  File "<__array_function__ internals>", line 5, in hstack
  File "/usr/local/lib/python3.9/site-packages/numpy/core/shape_base.py", line 345, in hstack
    return _nx.concatenate(arrs, 1)
  File "<__array_function__ internals>", line 5, in concatenate
ValueError: need at least one array to concatenate

Any clue on what has changed so that it is no longer working?

CodePudding user response:

The issue is here:

    markers = np.zeros_like(image, dtype=np.uint)
    markers[image < image.mean() - image.std() / 2.0] = 1
    markers[image > image.mean()   image.std() / 2.0] = 2

Your image only contains values of 255. So image.mean() - image.std() / 2.0 is 255, and image.mean() image.std() / 2.0 is also 255, and no image pixels are < or > these values. Therefore, your markers array contains all zeros and there are no walkers, which causes the error. I'm not sure what the old behaviour would have been.

Here's a more minimal reproducer causing the same error:

import numpy as np
from skimage import segmentation

image = np.random.random((5, 5))
labels = np.zeros((5, 5), dtype=int)
segmented = segmentation.random_walker(image, labels)

Either way, the error raised should be less obscure, so I've created an issue in the scikit-image repo: scikit-image/scikit-image#6561.

  • Related