使用 numpy.reshape() 反转 skimage view_as_blocks()
Reverse skimage view_as_blocks() with numpy.reshape()
我想将具有 2 个通道的 4x4 图像分成多个不重叠的正方形。
之后,我想重建镜像。
from skimage.util import view_as_blocks
# create testM array
array([[[[0.53258505, 0.31525832, 0.21378392, 0.5019507 ],
[0.31612498, 0.24320562, 0.93560226, 0.08232264],
[0.89784454, 0.12741783, 0.88049819, 0.29542855],
[0.11336386, 0.71023215, 0.45679456, 0.2318959 ]],
[[0.61038755, 0.74389586, 0.85199794, 0.46680889],
[0.01701045, 0.93953861, 0.03183684, 0.00740579],
[0.58878569, 0.71348253, 0.33221104, 0.12276253],
[0.04026615, 0.53837528, 0.06759152, 0.27477069]]]])
# use view_as_blocks() to get "grid" image
testB = view_as_blocks(testM, block_shape=(1,2,2,2)).reshape(-1,*(1,2,2,2))
现在我有这个数组的多个块,大小为 2x2:
array([[[[[0.53258505, 0.31525832],
[0.31612498, 0.24320562]],
...
[[0.33221104, 0.12276253],
[0.06759152, 0.27477069]]]]])
但是,我无法将它重塑回原来的形状:
testB.reshape(1,2,4,4)
导致这个。每个 "block" 只是一个接一个地附加值,但不被视为一个块。
array([[[[0.53258505, 0.31525832, 0.31612498, 0.24320562],
[0.61038755, 0.74389586, 0.01701045, 0.93953861],
[0.21378392, 0.5019507 , 0.93560226, 0.08232264],
[0.85199794, 0.46680889, 0.03183684, 0.00740579]],
[[0.89784454, 0.12741783, 0.11336386, 0.71023215],
[0.58878569, 0.71348253, 0.04026615, 0.53837528],
[0.88049819, 0.29542855, 0.45679456, 0.2318959 ],
[0.33221104, 0.12276253, 0.06759152, 0.27477069]]]])
在使用 reshape()
之前,我已经尝试了多次 .swapaxes()
,但就是无法正常工作。
发生的事情是您的 .reshape((-1, 1, 2, 2, 2))
,即您对块的线性化,导致复制:
import numpy as np
from skimage.util import view_as_blocks
arr = np.arange(24).astype(np.uint8).reshape((4, 6))
blocked = view_as_blocks(arr, (2, 3))
blocked_reshaped = blocked.reshape((-1, 2, 3))
print(arr.shape)
print(arr.strides)
print(blocked.shape)
print(blocked.strides)
print(blocked_reshaped.shape)
print(blocked_reshaped.strides)
print(np.may_share_memory(blocked, blocked_reshaped))
结果:
(4, 6)
(6, 1)
(2, 2, 2, 3)
(12, 3, 6, 1)
(4, 2, 3)
(6, 3, 1)
False
步幅是一个线索,表明数组的元素在底层内存中不再处于相同的线性顺序,因此重塑会导致您观察到的奇怪换位:
block_reshaped_orig = blocked_reshaped.reshape((4, 6))
print(arr)
print(block_reshaped_orig)
结果:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
[[ 0 1 2 6 7 8]
[ 3 4 5 9 10 11]
[12 13 14 18 19 20]
[15 16 17 21 22 23]]
我看到两个选项:
- 如果您可以避免重塑和复制,那么最后的重塑调用就可以正常工作。
- 如果您需要对正在执行的其他一些处理进行重塑,那么有点讽刺的是,您可以使用另一个
view_as_blocks
调用并重塑以恢复原始顺序:
print(
view_as_blocks(blocked_reshaped_orig, (2, 3)).reshape((4, -1))
)
结果:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
希望对您有所帮助!
In [30]: testM=np.array([[[[0.53258505, 0.31525832, 0.21378392, 0.5019507 ],
...: [0.31612498, 0.24320562, 0.93560226, 0.08232264],
...: [0.89784454, 0.12741783, 0.88049819, 0.29542855],
...: [0.11336386, 0.71023215, 0.45679456, 0.2318959 ]],
...:
...: [[0.61038755, 0.74389586, 0.85199794, 0.46680889],
...: [0.01701045, 0.93953861, 0.03183684, 0.00740579],
...: [0.58878569, 0.71348253, 0.33221104, 0.12276253],
...: [0.04026615, 0.53837528, 0.06759152, 0.27477069]]]])
...:
In [31]: testM.shape
Out[31]: (1, 2, 4, 4)
In [32]: from skimage.util import view_as_blocks
In [33]: testB = view_as_blocks(testM, block_shape=(1,2,2,2))
In [34]: testB.shape
Out[34]: (1, 1, 2, 2, 1, 2, 2, 2)
这真的是你想要的造型吗?无论如何,应用重塑,结合最初的 4 个维度:
In [36]: testB.reshape(-1,*(1,2,2,2)).shape
Out[36]: (4, 1, 2, 2, 2)
当我建议时
arr1.reshape(2,2,2,2,2).transpose(0,1,3,2,4).reshape(2,4,4)
我在想一个形状为 (2,4,4) 的源被分成 (2,2) windows。也就是说,每个 (4,4) 子数组变成了一个 (2,2,2,2) 数组,一个由 (2,2) 块组成的 (2,2) 数组。有许多尺寸 2 和 4 尺寸很难跟踪哪个是哪个。
这是我的目标转变:
In [62]: testM1 = testM[0,0,:,:]
In [63]: testM1
Out[63]:
array([[0.53258505, 0.31525832, 0.21378392, 0.5019507 ],
[0.31612498, 0.24320562, 0.93560226, 0.08232264],
[0.89784454, 0.12741783, 0.88049819, 0.29542855],
[0.11336386, 0.71023215, 0.45679456, 0.2318959 ]])
In [64]: testB1 = view_as_blocks(testM1, block_shape=(2,2))
In [65]: testB1.shape
Out[65]: (2, 2, 2, 2)
In [66]: testB1.transpose(0,2,1,3).reshape(4,4)
Out[66]:
array([[0.53258505, 0.31525832, 0.21378392, 0.5019507 ],
[0.31612498, 0.24320562, 0.93560226, 0.08232264],
[0.89784454, 0.12741783, 0.88049819, 0.29542855],
[0.11336386, 0.71023215, 0.45679456, 0.2318959 ]])
取一(4,4)块分成(2,2,2,2)windows,然后返回
我怀疑同样类型的转换适用于您更复杂的维度,但我没有时间(或兴趣)来计算细节。
我想将具有 2 个通道的 4x4 图像分成多个不重叠的正方形。
之后,我想重建镜像。
from skimage.util import view_as_blocks
# create testM array
array([[[[0.53258505, 0.31525832, 0.21378392, 0.5019507 ],
[0.31612498, 0.24320562, 0.93560226, 0.08232264],
[0.89784454, 0.12741783, 0.88049819, 0.29542855],
[0.11336386, 0.71023215, 0.45679456, 0.2318959 ]],
[[0.61038755, 0.74389586, 0.85199794, 0.46680889],
[0.01701045, 0.93953861, 0.03183684, 0.00740579],
[0.58878569, 0.71348253, 0.33221104, 0.12276253],
[0.04026615, 0.53837528, 0.06759152, 0.27477069]]]])
# use view_as_blocks() to get "grid" image
testB = view_as_blocks(testM, block_shape=(1,2,2,2)).reshape(-1,*(1,2,2,2))
现在我有这个数组的多个块,大小为 2x2:
array([[[[[0.53258505, 0.31525832],
[0.31612498, 0.24320562]],
...
[[0.33221104, 0.12276253],
[0.06759152, 0.27477069]]]]])
但是,我无法将它重塑回原来的形状:
testB.reshape(1,2,4,4)
导致这个。每个 "block" 只是一个接一个地附加值,但不被视为一个块。
array([[[[0.53258505, 0.31525832, 0.31612498, 0.24320562],
[0.61038755, 0.74389586, 0.01701045, 0.93953861],
[0.21378392, 0.5019507 , 0.93560226, 0.08232264],
[0.85199794, 0.46680889, 0.03183684, 0.00740579]],
[[0.89784454, 0.12741783, 0.11336386, 0.71023215],
[0.58878569, 0.71348253, 0.04026615, 0.53837528],
[0.88049819, 0.29542855, 0.45679456, 0.2318959 ],
[0.33221104, 0.12276253, 0.06759152, 0.27477069]]]])
在使用 reshape()
之前,我已经尝试了多次 .swapaxes()
,但就是无法正常工作。
发生的事情是您的 .reshape((-1, 1, 2, 2, 2))
,即您对块的线性化,导致复制:
import numpy as np
from skimage.util import view_as_blocks
arr = np.arange(24).astype(np.uint8).reshape((4, 6))
blocked = view_as_blocks(arr, (2, 3))
blocked_reshaped = blocked.reshape((-1, 2, 3))
print(arr.shape)
print(arr.strides)
print(blocked.shape)
print(blocked.strides)
print(blocked_reshaped.shape)
print(blocked_reshaped.strides)
print(np.may_share_memory(blocked, blocked_reshaped))
结果:
(4, 6)
(6, 1)
(2, 2, 2, 3)
(12, 3, 6, 1)
(4, 2, 3)
(6, 3, 1)
False
步幅是一个线索,表明数组的元素在底层内存中不再处于相同的线性顺序,因此重塑会导致您观察到的奇怪换位:
block_reshaped_orig = blocked_reshaped.reshape((4, 6))
print(arr)
print(block_reshaped_orig)
结果:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
[[ 0 1 2 6 7 8]
[ 3 4 5 9 10 11]
[12 13 14 18 19 20]
[15 16 17 21 22 23]]
我看到两个选项:
- 如果您可以避免重塑和复制,那么最后的重塑调用就可以正常工作。
- 如果您需要对正在执行的其他一些处理进行重塑,那么有点讽刺的是,您可以使用另一个
view_as_blocks
调用并重塑以恢复原始顺序:
print(
view_as_blocks(blocked_reshaped_orig, (2, 3)).reshape((4, -1))
)
结果:
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]]
希望对您有所帮助!
In [30]: testM=np.array([[[[0.53258505, 0.31525832, 0.21378392, 0.5019507 ],
...: [0.31612498, 0.24320562, 0.93560226, 0.08232264],
...: [0.89784454, 0.12741783, 0.88049819, 0.29542855],
...: [0.11336386, 0.71023215, 0.45679456, 0.2318959 ]],
...:
...: [[0.61038755, 0.74389586, 0.85199794, 0.46680889],
...: [0.01701045, 0.93953861, 0.03183684, 0.00740579],
...: [0.58878569, 0.71348253, 0.33221104, 0.12276253],
...: [0.04026615, 0.53837528, 0.06759152, 0.27477069]]]])
...:
In [31]: testM.shape
Out[31]: (1, 2, 4, 4)
In [32]: from skimage.util import view_as_blocks
In [33]: testB = view_as_blocks(testM, block_shape=(1,2,2,2))
In [34]: testB.shape
Out[34]: (1, 1, 2, 2, 1, 2, 2, 2)
这真的是你想要的造型吗?无论如何,应用重塑,结合最初的 4 个维度:
In [36]: testB.reshape(-1,*(1,2,2,2)).shape
Out[36]: (4, 1, 2, 2, 2)
当我建议时
arr1.reshape(2,2,2,2,2).transpose(0,1,3,2,4).reshape(2,4,4)
我在想一个形状为 (2,4,4) 的源被分成 (2,2) windows。也就是说,每个 (4,4) 子数组变成了一个 (2,2,2,2) 数组,一个由 (2,2) 块组成的 (2,2) 数组。有许多尺寸 2 和 4 尺寸很难跟踪哪个是哪个。
这是我的目标转变:
In [62]: testM1 = testM[0,0,:,:]
In [63]: testM1
Out[63]:
array([[0.53258505, 0.31525832, 0.21378392, 0.5019507 ],
[0.31612498, 0.24320562, 0.93560226, 0.08232264],
[0.89784454, 0.12741783, 0.88049819, 0.29542855],
[0.11336386, 0.71023215, 0.45679456, 0.2318959 ]])
In [64]: testB1 = view_as_blocks(testM1, block_shape=(2,2))
In [65]: testB1.shape
Out[65]: (2, 2, 2, 2)
In [66]: testB1.transpose(0,2,1,3).reshape(4,4)
Out[66]:
array([[0.53258505, 0.31525832, 0.21378392, 0.5019507 ],
[0.31612498, 0.24320562, 0.93560226, 0.08232264],
[0.89784454, 0.12741783, 0.88049819, 0.29542855],
[0.11336386, 0.71023215, 0.45679456, 0.2318959 ]])
取一(4,4)块分成(2,2,2,2)windows,然后返回
我怀疑同样类型的转换适用于您更复杂的维度,但我没有时间(或兴趣)来计算细节。