Skimage 重缩放分割蒙版

Skimage Rescale Segmentation Mask

有人能解释一下为什么我不能使用 here 中的 rescale() 来重新缩放分割蒙版吗?我尝试了以下方法:

>>> from skimage.transform import rescale as r
>>> a = np.ones((8,8), dtype=np.uint8)
>>> a
array([[1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8)
>>> r(a, 0.5, order=0)
array([[0.00392157, 0.00392157, 0.00392157, 0.00392157],
       [0.00392157, 0.00392157, 0.00392157, 0.00392157],
       [0.00392157, 0.00392157, 0.00392157, 0.00392157],
       [0.00392157, 0.00392157, 0.00392157, 0.00392157]])

我希望结果只包含 1,但这并没有发生。将分割掩码的高度和宽度缩小一半的正确方法是什么?

我认为我们可以将其归类为错误。您问题的根源是scikit-image查看数据类型的方式,本页对此进行了详细说明:

https://scikit-image.org/docs/dev/user_guide/data_types.html

在某种意义上,scikit-image 将这些值 (float 0.00392157) 视为“等同于”(uint8 1)。

您可以使用关键字参数 preserve_range=True 以保持比例作为输入,但您仍然会得到不正确的 dtype。

In [1]: import numpy as np
In [2]: from skimage import transform
In [3]: seg_mask = np.random.randint(0, 2**16, size=(16, 16)).astype(np.uint16)
In [4]: transform.rescale(seg_mask, 0.5, order=0)
Out[4]:
array([[0.5222858 , 0.55330739, 0.76211185, 0.61666285, 0.45897612,
        0.19795529, 0.52283513, 0.56203555],
       [0.57460899, 0.81582361, 0.61560998, 0.68281071, 0.3169604 ,
        0.19830625, 0.40459297, 0.48615244],
       [0.47759213, 0.62240024, 0.76609445, 0.333196  , 0.88154421,
        0.43877317, 0.50019074, 0.65618372],
       [0.84681468, 0.58448157, 0.56137942, 0.2824445 , 0.76746777,
        0.75156786, 0.47310597, 0.66036469],
       [0.18850996, 0.60334173, 0.25194171, 0.83747616, 0.56156252,
        0.61664759, 0.80070192, 0.48683909],
       [0.29718471, 0.3195697 , 0.32796216, 0.58196384, 0.81673915,
        0.50057221, 0.48458076, 0.27048142],
       [0.52285039, 0.35194934, 0.84243534, 0.68207828, 0.66150912,
        0.46347753, 0.23147936, 0.84484627],
       [0.51114672, 0.35536736, 0.87023728, 0.44734874, 0.6835584 ,
        0.54543374, 0.43472953, 0.78928817]])

In [5]: transform.rescale(seg_mask, 0.5, order=0, preserve_range=True)
Out[5]:
array([[34228., 36261., 49945., 40413., 30079., 12973., 34264., 36833.],
       [37657., 53465., 40344., 44748., 20772., 12996., 26515., 31860.],
       [31299., 40789., 50206., 21836., 57772., 28755., 32780., 43003.],
       [55496., 38304., 36790., 18510., 50296., 49254., 31005., 43277.],
       [12354., 39540., 16511., 54884., 36802., 40412., 52474., 31905.],
       [19476., 20943., 21493., 38139., 53525., 32805., 31757., 17726.],
       [34265., 23065., 55209., 44700., 43352., 30374., 15170., 55367.],
       [33498., 23289., 57031., 29317., 44797., 35745., 28490., 51726.]])

我认为对于 order=0 我们不应该改变数据类型,并且在这里提出了一个问题:

https://github.com/scikit-image/scikit-image/issues/5268

同时希望大家可以使用preserve_range=True.astype(int)解卡