像图像一样在正方形中重塑阵列

时间:2017-08-30 00:46:34

标签: python sorting numpy image-processing reshape

我想在python(最初是一个numpy数组)中重塑一个数组,使得第一个索引处的每个元素成为该数组中的正方形/象限,而不是采用行中所有元素的常规整形。

这是重塑+重组。

当然,最快/更好的方式:)

(首选python 3.5)

使用行,列,通道形状的数组。

作为一个例子,我创建了这个数组,您可以将其解释为图像。我已经为它添加了值,因此我们可以清楚地看到每个元素属于哪个行,列和通道:

import numpy as np

X = np.zeros((8,6,3)) #8 rows, 6 columns, 3 channels (imagine RGB channels)
for i in range(3):
    X[:,:,i] += i+1   #the last digit in the array elements are channels
for i in range(6):
    X[:,i,:] += 10*(i+1)  #the second digit in elements are columns
for i in range(8):
    X[i,:,:] += 100*(i+1) #the first digit in elements are rows  

打印此阵列显示:

[[[ 111.  112.  113.]
  [ 121.  122.  123.]
  [ 131.  132.  133.]
  [ 141.  142.  143.]
  [ 151.  152.  153.]
  [ 161.  162.  163.]]

 [[ 211.  212.  213.]
  [ 221.  222.  223.]
  [ 231.  232.  233.]
  [ 241.  242.  243.]
  [ 251.  252.  253.]
  [ 261.  262.  263.]]
 ...
  • 因此,很明显第一个索引被分组为图像行(第一个数字在每个较大的组中都是常量)
  • 第二个索引是列,它们在大的
  • 中的每个较小的组中发生变化
  • 最后一个索引是渠道,它们单独更改,小元素内的元素元素。

定期重塑不符合我的条件

现在,假设我想要将这个数组重新整形为12个方格,每个方格为2 x 2(两行和两列),将通道保持为最后一个维度。

如果我只是print(X.reshape(12,2,2,3)),我就明白了:

[
    [
        [
            [ 111.  112.  113.]
            [ 121.  122.  123.]
        ]
        [
            [ 131.  132.  133.]
            [ 141.  142.  143.]
        ]
    ]
    [
        [
            [ 151.  152.  153.]
            [ 161.  162.  163.]
        ]
        [
            [ 211.  212.  213.]
            [ 221.  222.  223.]
        ]
    ]

....

第一个索引将所有第一行的元素分组(它们以1开头)。因此,它不是在图像中采用“正方形”,而是将事物分组成直线。它从不占用第2行中的元素,直到获取第1行中的所有列。

预期结果

如何正确有效地重塑它,以便第一个索引返回正方形(2行,2列),如下所示:

[
    [
        [
            [ 111.  112.  113.]
            [ 121.  122.  123.]
        ]
        [
            [ 211.  212.  213.]
            [ 221.  222.  223.]             
        ]
    ]
    [
        [
            [ 131.  132.  133.]
            [ 141.  142.  143.]
        ]
        [
            [ 231.  232.  233.]
            [ 241.  242.  243.]                
        ]
    ]
    [
        [
            [ 151.  152.  153.]
            [ 161.  162.  163.]
        ]
        [
            [ 251.  252.  253.]
            [ 261.  262.  263.]
        ]
    ]
    [
        [
            [ 311.  312.  313.]
            [ 321.  322.  323.]
        ]
        [
            [ 411.  412.  413.]
            [ 421.  422.  423.]
        ]
    ]

   ....

1 个答案:

答案 0 :(得分:2)

您需要reshape + transpose/swapaxes + reshape

X.reshape(4,2,3,2,3).swapaxes(1,2).reshape(12,2,2,3)

给出:

array([[[[ 111.,  112.,  113.],
         [ 121.,  122.,  123.]],

        [[ 211.,  212.,  213.],
         [ 221.,  222.,  223.]]],


       [[[ 131.,  132.,  133.],
         [ 141.,  142.,  143.]],

        [[ 231.,  232.,  233.],
         [ 241.,  242.,  243.]]],


       [[[ 151.,  152.,  153.],
         [ 161.,  162.,  163.]],

        [[ 251.,  252.,  253.],
         [ 261.,  262.,  263.]]],


       [[[ 311.,  312.,  313.],
         [ 321.,  322.,  323.]],

        [[ 411.,  412.,  413.],
         [ 421.,  422.,  423.]]],