問題描述
我有一個尺寸為:Deep x Weight x Height
的 3D 圖片(例如:10x20x30
,表示 10 張圖片,每張圖片的尺寸為 20x30代碼>.
I have a 3D image with size: Deep x Weight x Height
(for example: 10x20x30
, means 10 images, and each image has size 20x30
.
給定一個補丁大小為pd x pw x ph
(如pd
pd/2 x pw/2 x ph/2
.我們把時間t
到中心點時間t+1
的距離稱為stride
,例如stride=2代碼>.
Given a patch size is pd x pw x ph
(such as pd <Deep, pw<Weight, ph<Height
), for example patch size: 4x4x4
. The center point location of the path will be: pd/2 x pw/2 x ph/2
. Let's call the distance between time t
and time t+1
of the center point be stride
, for example stride=2
.
我想將原始 3D 圖像提取成上面給出的大小和步幅的塊.我怎樣才能在python中做到這一點?謝謝
I want to extract the original 3D image into patches with size and stride given above. How can I do it in python? Thank you
.
推薦答案
使用np.lib.stride_tricks.as_strided
.此解決方案不需要跨步來劃分輸入堆棧的相應維度.它甚至允許重疊補丁(只是在這種情況下不要寫入結果,或者制作副本.).因此,它比其他方法更靈活:
Use np.lib.stride_tricks.as_strided
. This solution does not require the strides to divide the corresponding dimensions of the input stack. It even allows for overlapping patches (Just do not write to the result in this case, or make a copy.). It therefore is more flexible than other approaches:
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], '
')
print(x[:, 0, :], '
')
print(x[0, ...], '
')
輸出:
[[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]]
解釋.Numpy 數組按步長組織,每個維度一個,數據點 [x,y,z] 位于內存地址 base + stridex * x + stridey * y + stridez * z 處.
Explanation. Numpy arrays are organised in terms of strides, one for each dimension, data point [x,y,z] is located in memory at address base + stridex * x + stridey * y + stridez * z.
stride_tricks.as_strided
工廠允許直接操作與給定數組共享其內存的新數組的步幅和形狀.僅當您知道自己在做什么時才嘗試此操作,因為不執行任何檢查,這意味著您可以通過尋址越界內存來開槍.
The stride_tricks.as_strided
factory allows to directly manipulate the strides and shape of a new array sharing its memory with a given array. Try this only if you know what you're doing because no checks are performed, meaning you are allowed to shoot your foot by addressing out-of-bounds memory.
代碼使用此函數將三個現有維度中的每一個拆分為兩個新維度,一個用于對應的塊內坐標(這將與原始維度具有相同的步幅,因為塊中的相鄰點對應于相鄰的整個堆棧中的點)和沿該軸的塊索引的一維;這將具有步幅 = 原始步幅 x 塊步幅.
The code uses this function to split up each of the three existing dimensions into two new ones, one for the corresponding within block coordinate (this will have the same stride as the original dimension, because adjacent points in a block corrspond to adjacent points in the whole stack) and one dimension for the block index along this axis; this will have stride = original stride x block stride.
代碼所做的只是計算正確的步幅和尺寸(= 沿三個軸的塊尺寸和塊數).
All the code does is computing the correct strides and dimensions (= block dimensions and block counts along the three axes).
由于數據與原始數組共享,當我們將6d數組的所有點設置為1時,它們也被設置在原始數組中,暴露了演示中的塊結構.請注意,函數最后一行中注釋掉的 reshape
會破壞此鏈接,因為它會強制進行復制.
Since the data are shared with the original array, when we set all points of the 6d array to 1, they are also set in the original array exposing the block structure in the demo. Note that the commented out reshape
in the last line of the function breaks this link, because it forces a copy.
這篇關于如何從python中的3D圖像中提取補丁?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!