【问题标题】:How to extract paches from 3D image in python?如何从python中的3D图像中提取补丁?
【发布时间】:2017-07-09 06:44:55
【问题描述】:

我有一个大小为:Deep x Weight x Height 的 3D 图像(例如: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中做到这一点?谢谢

【问题讨论】:

  • 您是否尝试在 (time,x,y) 空间中跟踪大图像中的一些细节?您想为已知 (x0,y0,t0) 生成微空间 ([t0-dt, t0+dt] , [x0-dx, x0+dx],[y0-dy, y0+dy]) 吗?跨度>
  • 其实我不在乎时间。我只想将图像提取到给定图像和补丁大小的补丁中。补丁将从左到右进行扫描,并且深入。该过程喜欢卷积,但不是计算值,而是提取补丁

标签: python numpy image-processing computer-vision


【解决方案1】:

使用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')

输出:

[[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 处。

stride_tricks.as_strided 工厂允许直接操作与给定数组共享其内存的新数组的步长和形状。仅当您知道自己在做什么时才尝试此操作,因为不执行任何检查,这意味着您可以通过寻址越界内存来开枪。

代码使用此函数将三个现有维度中的每一个拆分为两个新维度,一个用于对应的块内坐标(这将与原始维度具有相同的步幅,因为块中的相邻点对应于相邻的整个堆栈中的点)和沿该轴的块索引的一维;这将具有步幅 = 原始步幅 x 块步幅。

代码所做的只是计算正确的步幅和尺寸(= 沿三个轴的块尺寸和块数)。

由于数据与原始数组共享,当我们将6d数组的所有点设置为1时,它们也被设置在原始数组中,暴露了演示中的块结构。请注意,函数最后一行中注释掉的 reshape 会破坏此链接,因为它会强制复制。

【讨论】:

  • 感谢您的解决方案。你能解释一下这样做的想法吗?
  • @user3051460 我试过了(见帖子);我还稍微简化了代码。
【解决方案2】:

skimage 模块为您提供与view_as_blocks 的集成解决方案。 来源在线。

注意选择pd, pw, ph的倍数Deep,Weight,Height,因为as_strided不检查边界。

【讨论】:

  • 使用as_strided 的全部意义在于满足划分输入维度的块维度。只有基于 reshape 的解决方案具有此限制。
  • 嗯。我不太确定 op 的目标。这似乎是(t,x,y)空间中的跟踪任务。在这种情况下,不必重新定义 strides……我会问他。
  • @B.M.这是非常好的库。但是如果两个补丁重叠会发生什么。这意味着步幅小于 Weight/2 或 Height/2。
  • 也许view_as_windows可以在这种情况下帮助你?
  • @B.M:你是对的。 as_strided 不检查绑定。我正在尝试view_as_windows。你觉得view_as_windows 支持随机选择补丁吗?
猜你喜欢
  • 2017-07-15
  • 2019-06-17
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
相关资源
最近更新 更多