我正在尝试读取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
。因此,假设您的图片是rgb
。 quickshift()
的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)