In tensorflow, there is a pixel-shuffle method called depth_to_space
. What it does is the following:
Suppose we have an image (an array) with dimensions (4,4,4). The above method shuffles the values of this array so that we get an array of size (16,16,1) in a way depicted in the image below:
I tried now for a few hours to recreate this method in numpy using plane numpy functions like reshape, transpose etc. however I am not able to succeed. Does anyone know how to implement it?
A very similar problem can be found in How to implement tf.space_to_depth with numpy?. However, this question considers the space_to_depth
method, which is the inverse operation.
Lockhart is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
Here is a “channels-first” solution (i.e. assuming your array dimensions are ordered channels×height×width):
import numpy as np
# "Channels-first" version
a = np.ones((1, 3, 3), dtype=int) * np.arange(1,5)[:, np.newaxis, np.newaxis] # 4×3×3
c, h, w = a.shape # channels, height, width
p = int(np.sqrt(c)) # height and width of one "patch"
a_flat = a.reshape(p, p, h, w).transpose(2, 0, 3, 1).reshape(h * p, w * p) # 6×6
print(a)
# [[[1 1 1]
# [1 1 1]
# [1 1 1]]
# [[2 2 2]
# [2 2 2]
# [2 2 2]]
# [[3 3 3]
# [3 3 3]
# [3 3 3]]
# [[4 4 4]
# [4 4 4]
# [4 4 4]]]
print(a_flat)
# [[1 2 1 2 1 2]
# [3 4 3 4 3 4]
# [1 2 1 2 1 2]
# [3 4 3 4 3 4]
# [1 2 1 2 1 2]
# [3 4 3 4 3 4]]
And here is the corresponding “channels-last” version (i.e. assuming your array dimensions are ordered height×width×channels):
import numpy as np
# "Channels-last" version
a = np.ones((3, 3, 1), dtype=int) * np.arange(1, 5) # 3×3×4
h, w, c = a.shape # height, width, channels
p = int(np.sqrt(c)) # height and width of one "patch"
a_flat = a.reshape(h, w, p, p).transpose(0, 2, 1, 3).reshape(h * p, w * p) # 6×6
print(a)
# [[[1 2 3 4]
# [1 2 3 4]
# [1 2 3 4]]
# [[1 2 3 4]
# [1 2 3 4]
# [1 2 3 4]]
# [[1 2 3 4]
# [1 2 3 4]
# [1 2 3 4]]]
print(a_flat)
# [[1 2 1 2 1 2]
# [3 4 3 4 3 4]
# [1 2 1 2 1 2]
# [3 4 3 4 3 4]
# [1 2 1 2 1 2]
# [3 4 3 4 3 4]]