Numpy с python: конвертировать 3d массив в 2d

Скажем, что у меня есть цветное изображение, и, естественно, это будет представлено трехмерным массивом в python, например, о форме (n x m x 3) и называть его img.

Я хочу новый 2-й массив, назовите его "narray", чтобы иметь форму (3, nxm), так что каждая строка этого массива содержит "сплющенную" версию каналов R, G и B соответственно. Более того, у него должно быть свойство, что я могу легко восстановить обратно любой из исходного канала чем-то вроде

narray[0,].reshape(img.shape[0:2])    #so this should reconstruct back the R channel.

Вопрос в том, как я могу построить "narray" из "img"? Простая img.reshape(3, -1) не работает, так как порядок элементов для меня нежелателен.

Спасибо

Ответ 1

Вам нужно использовать np.transpose для изменения размеров. Теперь n x m x 3 нужно преобразовать в 3 x (n*m), поэтому отправьте последнюю ось на передний план и сдвиньте вправо порядок остальных осей (0,1). Наконец, измените форму, чтобы иметь строки 3. Таким образом, реализация будет -

img.transpose(2,0,1).reshape(3,-1)

Пример прогона -

In [16]: img
Out[16]: 
array([[[155,  33, 129],
        [161, 218,   6]],

       [[215, 142, 235],
        [143, 249, 164]],

       [[221,  71, 229],
        [ 56,  91, 120]],

       [[236,   4, 177],
        [171, 105,  40]]])

In [17]: img.transpose(2,0,1).reshape(3,-1)
Out[17]: 
array([[155, 161, 215, 143, 221,  56, 236, 171],
       [ 33, 218, 142, 249,  71,  91,   4, 105],
       [129,   6, 235, 164, 229, 120, 177,  40]])

Ответ 2

Допустим, у нас есть массив img размером mxnx 3 для преобразования в массив new_img размером 3 x (m*n)

new_img = img.reshape((img.shape[0]*img.shape[1]), img.shape[2])
new_img = new_img.transpose()

Ответ 3

Если у вас установлен модуль scikit, то вы можете использовать rgb2grey (или rgb2gray), чтобы сделать фотографию от цветного до серого (от 3D до 2D)

from skimage import io, color

lina_color = io.imread(path+img)
lina_gray = color.rgb2gray(lina_color)

In [33]: lina_color.shape
Out[33]: (1920, 1280, 3)

In [34]: lina_gray.shape
Out[34]: (1920, 1280)