一次性切片两幅图像的不同区域

时间:2019-05-19 12:15:47

标签: numpy

一次性切片两个图像的不同区域

我有两张[高度,宽度,通道]尺寸和大小相同的图像。我想一次用相同大小的内核(例如5 x 5)在不同位置切片两个图像。例如,对于图像一,切片区域为[125px,125px]至[130px,130px];对于第二张图片,切片范围为[140px,140px]至[145px,145px]。

我使用了以下代码     imgs [:, yst:yend,xst:xend] 其中yst分别是两个图像的起始坐标的两次输入数组(即[125,140])。 yend同样用于结尾坐标。宽度轴坐标的xst和xend也是如此。

代码没有得到两个切片区域,而是得到了四个区域。也就是说,两个切片已应用于每个图像。

我期望的是将第一切片应用于第一图像,将第二切片应用于第二图像。我尝试了各种尺寸组合,但到目前为止,它们都没有按我的要求工作。我最终将它们一一循环。但是我的直觉告诉我这可以一口气完成。有人可以帮忙吗?

预先感谢

1 个答案:

答案 0 :(得分:0)

我看到了两种选择来实现您想要的。

  1. 转到花式索引
  2. 使用大步魔术

后者速度更快,但是有点危险(尺寸设置魔术中的错字可能会严重破坏脚本):

这里是一个例子:

import numpy as np
from numpy.lib.stride_tricks import as_strided
from scipy.misc import face
from timeit import timeit

def fancy_idx():
    ino, y, x = np.ogrid[:nim,:yw,:xw]
    ywo, xwo = ywoff.reshape(-1,1,1), xwoff.reshape(-1,1,1)
    return im[ino, ywo+y, xwo+x]

def stride_trx():
    nim, y, x = im.shape
    st = im.strides
    wins = as_strided(im, (nim, y-yw+1, x-xw+1, yw, xw), (*st, *st[1:]))
    return wins[np.arange(nim), ywoff, xwoff]

# set up example
# use the scipy example image
# use the color channels (RGB) as individual images
im = np.ascontiguousarray(np.moveaxis(face(), 2, 0))
nim = len(im)
# set the window height and width
yw, xw = 150, 200
# set the top left corners for window in each image
ywoff, xwoff = np.array([[510,530,520],[700,720,750]])

# test
assert (fancy_idx()==stride_trx()).all()

print(timeit(fancy_idx, number=1000))
print(timeit(stride_trx, number=1000))

样品运行:

0.4873827249975875    # fancy indexing
0.028213004930876195  # stride tricks

一些解释:

  1. 花式索引:此方法分别处理每个像素,这是灵活,安全但缓慢的
  2. 大步小窍门:这种方法速度更快,因为只有每个窗口的左上角都被看中了,窗口本身是通过切片创建的

    它如何工作?我们本质上是通过复制y和x轴(在管理员中,而不是数据中)创建5D数组。这样,我们可以使用y和x的第一个副本选择偏移量,并使用y和x的第二个副本进行切片