今天遇到一个数组按照排布规律转变为4个数组的方法,通过转置与重塑在高维度实现,源代码如下:
def downsample_subpixel_new(x,downscale=2):
[b, h, w, c] = x.get_shape().as_list()
s = downscale
if h%s != 0 or w%s != 0:
print('!!!!Notice: the image size can not be downscaled by current scale')
exit()
x_1 = tf.transpose(x, [0, 3, 1, 2])
x_2 = tf.reshape(x_1, [b, c, h, w // s, s])
x_3 = tf.reshape(x_2, [b, c, h // s, s, w // s, s])
x_4 = tf.transpose(x_3, [0, 1, 2, 4, 3, 5])
x_5 = tf.reshape(x_4, [b, c, h // s, w // s, s * s])
x_6 = tf.transpose(x_5, [0, 2, 3, 1, 4])
x_output = tf.reshape(x_6, [b, h // s, w // s, s * s * c])
return x_output
上面代码实现的效果为下图左边一个数组变为右边四个数组:
其中transpose为转置,数组相应维度进行交换
reshape重塑数组形状,从最后数组一维开始重塑,当维度较小时容易理解,维度超过三维时以下面例子直观展示:
为便于观察,假设开始时数组a为1到16的数字组成的维度为[1,4,4,1]的数组
>>> a=np.array([[[[1],[2],[3],[4]],[[5],[6],[7],[8]],[[9],[10],[11],[12]],[[13],[14],[15],[16]]]])
>>> a
array([[[[ 1],
[ 2],
[ 3],
[ 4]],
[[ 5],
[ 6],
[ 7],
[ 8]],
[[ 9],
[10],
[11],
[12]],
[[13],
[14],
[15],
[16]]]])
>>> a.shape
(1, 4, 4, 1)
>>> a1=np.transpose(a,[0,3,1,2])
>>> a1
array([[[[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]]]])
>>> a2=np.reshape(a1,[1,1,4,2,2])
>>> a2
array([[[[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]],
[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]]]])
>>> a3=np.reshape(a2,[1,1,2,2,2,2])
>>> a3
array([[[[[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]]],
[[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]]]]])
>>> a4=np.transpose(a3,[0,1,2,4,3,5])
>>> a4
array([[[[[[ 1, 2],
[ 5, 6]],
[[ 3, 4],
[ 7, 8]]],
[[[ 9, 10],
[13, 14]],
[[11, 12],
[15, 16]]]]]])
>>> a5=np.reshape(a4,[1,1,2,2,4])
>>> a5
array([[[[[ 1, 2, 5, 6],
[ 3, 4, 7, 8]],
[[ 9, 10, 13, 14],
[11, 12, 15, 16]]]]])
>>> a6=np.transpose(a5,[0,2,3,1,4])
>>> a6
array([[[[[ 1, 2, 5, 6]],
[[ 3, 4, 7, 8]]],
[[[ 9, 10, 13, 14]],
[[11, 12, 15, 16]]]]])
>>> a7=np.reshape(a6,[1,2,2,4])
>>> a7
array([[[[ 1, 2, 5, 6],
[ 3, 4, 7, 8]],
[[ 9, 10, 13, 14],
[11, 12, 15, 16]]]])
可以看到a7数组已经完成了规律的下采样,其中1,3,9,11坐标的像素对应右图第一个数组