提问人:bhomaidan90 提问时间:11/6/2023 最后编辑:bhomaidan90 更新时间:11/6/2023 访问量:72
使用无循环的索引范围从 np 数组中提取多个 ROI
Extract multiple roi's from np array using indices ranges without loops
问:
我有一个形状为 640 x 480: 的 numpy 数组:,并且我有一个最小值,最大行、列范围:np.ones((640, 480))
u_min=[497, 157, 493, 137, 567]
v_min=[ 36, 46, 208, 412, 418]
u_max=[502, 162, 498, 142, 572]
v_max=[41, 51 213, 417, 423]
我试过:
import numpy as np
arr = np.ones((640, 480))
u_min= np.array([497, 157, 493, 137, 567], dtype=np.int32)
u_max= np.array([502, 162, 498, 142, 572], dtype=np.int32)
v_min= np.array([36, 46, 208, 412, 418], dtype=np.int32)
v_max= np.array([41, 51, 213, 417, 423], dtype=np.int32)
rois = arr[u_min:u_max, v_min:v_max]
但我收到一个错误:
TypeError: only integer scalar arrays can be converted to a scalar index
我想在不循环的情况下以矢量化的方式对 numpy 数组进行切片。你能告诉我我该怎么做吗?谢谢
答:
我不认为花哨的索引涵盖了这一点。或者,如果是这样,那么不是通过简单的切片,而是通过明确的索引。因此,最有效的方法是
rois = np.stack([a[ul:uh, vl:vh] for ul, uh, vl, vh
in zip(u_min, u_max, v_min, v_max)])
请注意,这仅是因为您的 ROI 都是相同的形状。我认为这是故意的。
评论
(25,25)
(5,5,5)
你的直觉是对的:你正在尝试使用多个切片来获得多个子数组的组合。但是,实际上被解释为对 Numpy 数组对象没有意义。取而代之的是,您需要将最大值和最小值作为对,因此它们定义了数组的一个切片。rois = arr[u_min:u_max, v_min:v_max]
rois = arr[<list>:<list>, <list>:<list>]
让我们首先将 和 值压缩在一起。这将创建一个对象。当我们索引 numpy 数组时,每个切片都确定一个开始和停止点(参见上面的链接)。u_min
u_max
tuple
slice
import numpy as np
arr = np.ones((640, 480))
u_min=[497, 157, 493, 137, 567]
v_min=[ 36, 46, 208, 412, 418]
u_max=[502, 162, 498, 142, 572]
v_max=[41, 51, 213, 417, 423]
u_slices = tuple(slice(u1, u2) for u1, u2 in zip(u_min, u_max))
v_slices = tuple(slice(v1, v2) for v1, v2 in zip(v_min, v_max))
需要注意的是,包括起始值,但不包括止损值!如果要包含止损值,请更改上述行中的 -> 和 ->。我们的切片是:u2
u2 + 1
v2
v2 + 1
> u_slices
(slice(497, 502, None),
slice(157, 162, None),
slice(493, 498, None),
slice(137, 142, None),
slice(567, 572, None))
接下来,我们需要一种方法在对 Numpy 数组的同一调用中使用多个切片。我们将使用此答案中的 R 技巧类。
> arr[np.r_.__getitem__(u_slices), :].shape
(25, 480)
这将选择 25 行(如果使用 ),则为 30 行。由于 Numpy 处理多索引的方式,我们需要在选择的末尾使用。这告诉 Numpy,我们只想要轴 0 和轴 1 的所有给定值。完成此选择后,我们可以使用 'v_slices.我们的最终结果:u2 + 1
, :]
u_slices
> result = arr[np.r_[u_slices], :][: , np.r_[v_slices]]
> result.shape
(25, 25)
评论
__getitem__(u_slices)
[u_slices]
arr[np.r_[u_slices], np.r_[v_slices]]
__getitem__
arr[np.r_[u_slices], :][: , np.r_[v_slices]]
[]
上一个:零拷贝按步骤引用字节片
评论
lib.stride_tricks.sliding_window_view