use*_*460 5 python numpy image-processing computer-vision
我有一个大小的3D图像:( Deep x Weight x Height例如:10x20x30,表示10张图像,每张图像都有大小20x30.
给定补丁大小pd x pw x ph(例如pd <Deep, pw<Weight, ph<Height),例如补丁大小:4x4x4.路径的中心点位置为:pd/2 x pw/2 x ph/2.让我们把时间之间的距离t和时间t+1的中心点是stride,例如stride=2.
我想将原始3D图像提取到上面给出的大小和步幅的补丁中.我怎么能在python中做到这一点?谢谢
.
使用np.lib.stride_tricks.as_strided.这种解决方案不要求步幅来划分输入堆栈的相应尺寸.它甚至允许重叠补丁(在这种情况下,不要写入结果,或者复制.).因此,它比其他方法更灵活:
import numpy as np
from numpy.lib import stride_tricks
def cutup(data, blck, strd):
sh = np.array(data.shape)
blck = np.asanyarray(blck)
strd = np.asanyarray(strd)
nbl = (sh - blck) // strd + 1
strides = np.r_[data.strides * strd, data.strides]
dims = np.r_[nbl, blck]
data6 = stride_tricks.as_strided(data, strides=strides, shape=dims)
return data6#.reshape(-1, *blck)
#demo
x = np.zeros((5, 6, 12), int)
y = cutup(x, (2, 2, 3), (3, 3, 5))
y[...] = 1
print(x[..., 0], '\n')
print(x[:, 0, :], '\n')
print(x[0, ...], '\n')
Run Code Online (Sandbox Code Playgroud)
输出:
[[1 1 0 1 1 0]
[1 1 0 1 1 0]
[0 0 0 0 0 0]
[1 1 0 1 1 0]
[1 1 0 1 1 0]]
[[1 1 1 0 0 1 1 1 0 0 0 0]
[1 1 1 0 0 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0]
[1 1 1 0 0 1 1 1 0 0 0 0]
[1 1 1 0 0 1 1 1 0 0 0 0]]
[[1 1 1 0 0 1 1 1 0 0 0 0]
[1 1 1 0 0 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0]
[1 1 1 0 0 1 1 1 0 0 0 0]
[1 1 1 0 0 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0]]
Run Code Online (Sandbox Code Playgroud)
说明.Numpy数组按步幅组织,每个维度一个,数据点[x,y,z]位于内存地址库+ stridex*x + stridey*y + stridez*z.
该stride_tricks.as_strided工厂允许直接操纵的进展和新的数组与给定阵列共享其存储器的形状.只有当你知道自己在做什么时才尝试这个,因为没有进行任何检查,这意味着你可以通过解决越界记忆来射击你的脚.
代码使用此函数将三个现有维度中的每一个拆分为两个新维度,一个用于块坐标内的对应(这将与原始维度具有相同的步幅,因为块中的相邻点与相邻点中的相邻点相对应.整个堆栈)和沿该轴的块索引的一个维度; 这将有stride =原始步幅x块步幅.
所有代码都是计算正确的步幅和尺寸(=沿三个轴的块尺寸和块计数).
由于数据与原始数组共享,当我们将6d数组的所有点都设置为1时,它们也会在原始数组中设置,从而暴露演示中的块结构.请注意,reshape函数的最后一行中注释掉了此链接,因为它强制复制.