【问题标题】:How to return Scikit-image Segmentation in 3D array?如何在 3D 数组中返回 Scikit 图像分割?
【发布时间】:2019-06-12 18:08:22
【问题描述】:

我有一个四波段光栅图像(这是一个 3D 数组),我想逐波段分割图像。此栅格的形状(转换为 3D 数组后)为(12200, 7200, 4)

我尝试过使用 scikit-image:

skimage.segmentation.slic(image[, …])

skimage.segmentation.quickshift(image[, …])

结果只是一个二维数组(= 1 个波段栅格),形状为 (12200, 7200)。

该命令似乎使图像变平,我在他们的文档中找不到任何关于此事的内容。

这是我尝试过的:

from __future__ import print_function
from osgeo import gdal
import numpy as np
from skimage import io
from skimage.segmentation import felzenszwalb, slic, quickshift
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float

# The input 4-band TSX image
image = r'raw_img/09K0153_20140501T084638_TSX.tif'

#convert image to Np array
img = io.imread(image, as_gray=False, plugin="gdal")

# Run the quick shift segmentation
segments = quickshift(img, kernel_size=3, convert2lab=False, max_dist=6, ratio=0.5)

如何使用 Scikit-image 而不是 2D 生成 3D 分割结果(即输入:3D 数组,输出:3D 数组)?或者是否有其他库可以用于此目的?

【问题讨论】:

    标签: python image-segmentation gdal scikit-image


    【解决方案1】:

    欢迎使用 StackOverflow。

    确实,quickshift 算法只返回一个 (x, y) 掩码。你可以找到实现here。如果您为算法提供多个通道,它将考虑所有通道来计算分割掩码。

    如果您想将算法独立地应用于每个通道,则必须迭代地进行,例如使用以下代码

    from __future__ import print_function
    from osgeo import gdal
    import numpy as np
    from skimage import io
    from skimage.segmentation import felzenszwalb, slic, quickshift
    from skimage.segmentation import mark_boundaries
    from skimage.util import img_as_float
    
    # The input 4-band TSX image
    image = r'raw_img/09K0153_20140501T084638_TSX.tif'
    
    #convert image to Np array
    img = io.imread(image, as_gray=False, plugin="gdal")
    
    # Instantiate a segments array of same shape than image
    segments = np.zeros(img.shape)
    Nc = img.shape[-1] # number of channels
    
    # Run the quick shift segmentation for each channel
    for c in range(Nc):
        segments[:,:,c] = quickshift(img[:,:,c], kernel_size=3, convert2lab=False, max_dist=6, ratio=0.5)
    

    【讨论】:

    • 谢谢@Christian!这有帮助。我刚刚发现我也可以使用带有 multichannel=False 参数的 slic 分割。
    • 不客气!那么酷,只要知道quickshiftslic 是不同的算法(因此取决于你想要做什么......)。附注,如果您认为您的问题已得到解答,您应该mark it as answered。如果您认为使用slic 解决问题的新方法更好/更简单,您也可以回答自己的问题并将其标记为更好的解决方案:)
    【解决方案2】:

    如何生成 3D 分割结果(即输入:3D 数组, 输出:3D 数组)使用 Scikit-image,而不是 2D?

    让我们看看将 3D 分割结果作为 3D 数组的真正含义。让我们考虑如下所示的 3 通道图像。我们感兴趣的分割显示在蓝色虚线中。

    现在假设有一些算法可以为我们分割蓝色虚线段。但是那么如何表示蓝色虚线段呢? 如果它是一个矩形的正方形,我们可以在 3D numpy 数组(原始图像的 3D 切片)中表示该段。但是如果图像是任意形状的,那我们该怎么做呢? 使用掩码捕获分割信息。创建与图像大小相对应的掩码 2D 数组。假设我们的图像中只有一个片段。在这种情况下,图像片段内的所有像素在相应的掩码图像中都标记为 1。这是一个布尔掩码(1 段)。如果有多个段,则每个段中的像素作为唯一编号。

    这就是您看到quickshift 的结果是具有相同图像尺寸的二维数组的原因。结果是掩码,掩码中具有相同值的位置对应于表示切片的段(对于所有通道都是相同的)。但是,如果切片是任意形状,您将无法使用 numpy 数组来表示切片。

    只是补充一下,一次运行一个通道的quickshift 是一个坏主意,因为它使用由颜色信息和图像位置 2 组成的 5D 空间进行分割。一次在 1 个通道上使用它会给你带来糟糕的分割结果。

    【讨论】:

      猜你喜欢
      • 2020-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 2016-05-31
      • 2022-10-17
      • 1970-01-01
      相关资源
      最近更新 更多