在先通道和最后通道之间更改图像通道顺序的正确方法是啥?

Posted

技术标签:

【中文标题】在先通道和最后通道之间更改图像通道顺序的正确方法是啥?【英文标题】:What is the correct way to change image channel ordering between channels first and channels last?在先通道和最后通道之间更改图像通道顺序的正确方法是什么? 【发布时间】:2017-10-05 09:32:14 【问题描述】:

我一生都无法弄清楚如何切换图像排序。图像以 (x,x,3) 格式读取,theano 要求它是 (3,x,x) 格式。我尝试更改顺序 numpy.array([img[:,:,i] for i in range(3)])

我想它可以完成工作,但它既丑陋,我不知道如何反转它以恢复原始图像。

【问题讨论】:

试试img.transpose(2,0,1)img.transpose(2,1,0) 请考虑接受以下选项以将问题标记为已回答。 【参考方案1】:

如果您正在寻找最快的选项,请选择.transpose(...)。它甚至比np.einsum 还要快。

img = np.random.random((1000, 1000, 3))
img.shape
# (1000, 1000, 3)

%timeit img.transpose(2, 0, 1)
# 385 ns ± 1.11 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit np.rollaxis(img, -1, 0)
# 2.7 µs ± 50.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.einsum('ijk->kij', img)
# 2.75 µs ± 31.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.moveaxis(img, -1, 0)
# 7.26 µs ± 57.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

np.allclose(img.transpose(2, 0, 1), np.einsum('ijk->kij', img))
# True
np.allclose(img.transpose(2, 0, 1), np.moveaxis(img, -1, 0))
# True
np.allclose(img.transpose(2, 0, 1), np.rollaxis(img,-1, 0))
# True

【讨论】:

【参考方案2】:

使用np.moveaxis 是有效的,但我发现np.einsum 更快。

x = np.zeros((12,12,3))
%timeit np.moveaxis(x,-1,0)
#yields 7.46 µs ± 312 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit np.einsum('ijk->kij',x)
#yields 1.11 µs ± 31 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

【讨论】:

【参考方案3】:
x = np.zeros((12, 12, 3))
y = np.rollaxis(x, 2, 0)
y.shape

(3, 12, 12)

【讨论】:

【参考方案4】:

我同意@Qualia 的评论,np.moveaxis(a, source, destination) 更容易理解。这样就可以了:

x = np.zeros((12, 12, 3))
x.shape
#yields: 
(12, 12, 3)

x = np.moveaxis(x, -1, 0)
x.shape
#yields: 
(3, 12, 12)

【讨论】:

【参考方案5】:

重新排序数据

您可以使用numpy.rollaxis 将轴 3 滚动到位置 1(考虑到批量大小为维度 0)。

np.rollaxis(imagesArray, 3, 1)  

但是,如果您使用的是 keras,您可能希望更改其配置或按层定义它。如果你使用 Keras,Theano 不需要你做任何事情。

Keras 可以先配置通道或最后配置通道,此外还允许您在每个单独的层中定义它,因此您不必更改数据。

配置 keras

找到keras.json 文件并更改它。该文件通常安装在C:\Users\yourusername\.keras~/.keras 中,具体取决于您的操作系统。

根据需要将 "image_data_format": "channels_last" 更改为 "channels_first" 或反之亦然。

通常,使用“channels_last”不太麻烦,因为大量其他(非卷积)函数只能在最后一个轴上工作。

按层定义通道顺序。

Keras documentation 包含有关层参数的所有信息,包括 data_format 参数。

【讨论】:

我发现 np.moveaxis 更直观。

以上是关于在先通道和最后通道之间更改图像通道顺序的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Tensorflow 3通道颜色输入顺序

java:BufferedImage判断图像通道顺序并转RGB/BGR

将通道最后转换为通道第一图像

OpenCV的图像通道操作

使用Python,OpenCV获取更改像素,修改图像通道,剪裁ROI

opencv六通道矩阵乘法