我正在尝试读取4波段(红色,绿色,蓝色,近红外)的Geotiff(example data),并使用Python中的scikit-image模块执行quickshift segmentation

我创建了以下脚本(基于scikit example):

from __future__ import print_function
from osgeo import gdal
import matplotlib.pyplot as plt
import numpy as np

from skimage.segmentation import felzenszwalb, slic, quickshift
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float

image = r'C:\path\to\my\geotiff.tif'
img = io.imread(image, as_grey=False, plugin="gdal")
segments_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)


我收到以下错误:

ValueError: the input array must be have a shape == (.., ..,[ ..,] 3)), got (4, 436, 553)


我很确定需要以某种方式重塑numpy数组。如何将多波段Geotiff正确地读入numpy数组并执行图像分割?

最佳答案

我相信您的问题是quickshift()认为您的图片是rgb。我从您提供的链接中下载了随机图像,并将其读入skimage。

img = io.imread('./m_4111722_ne_11_1_20100704.tif')


我将其大小调整为128x128x4(以简化计算)

img = transform.resize(img, (128, 128, 4))


然后跑quickshift()

segments = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)


并得到相同的错误。

ValueError: the input array must be have a shape == (.., ..,[ ..,] 3)), got (128, 128, 4)


它说在堆栈跟踪中更高

skimage/segmentation/_quickshift.pyx inskimage.segmentation._quickshift.\
quickshift (skimage/segmentation/_quickshift.c:1710)()

/****/****/anaconda/lib/python2.7/site-packages/skimage/color/colorconv.pyc in rgb2lab(rgb)
    901     This function uses rgb2xyz and xyz2lab.
    902     """
--> 903     return xyz2lab(rgb2xyz(rgb))


因此,您可以看到_quickshift.pyx试图先转换rgb --> xyz,然后再转换xyz --> lab。因此,假设您的图片是rgbquickshift()skimage docs表示它具有默认为convert2lab的标志True


  convert2lab:bool,可选(默认为True),在分割之前是否应将输入转换为Lab色彩空间。为此,假定输入为RGB。


如果我在将该标志设置为False的情况下重新运行您的功能

segments = quickshift(img, kernel_size=3, convert2lab=False, max_dist=6, ratio=0.5)


它运行。

plt.imshow(segments);




编辑:

顺便说一句,我注意到您的图像形状为(4, 436, 553),这也是有问题的。 skimage期望颜色通道为最后。这可以用

img = img.transpose(1, 2, 0)

09-11 17:27