Python 如何在没有循环的情况下均匀地裁剪图像

Python 如何在没有循环的情况下均匀地裁剪图像,python,numpy,crop,Python,Numpy,Crop,假设我有一个np.数组(图) 我怎样才能把它分成4种作物 [[1,2], [[3,4], [[9,10], [[11,12], [5,6]] [7,8]] [13,14]] [15,16]] 我知道的唯一方法是使用循环指定img[x\u start:x\u end,y\u start:y\u end]。 但对于大型3D体积而言,这非常耗时。 在某些算法中,NumPy库本身的性能似乎比循环更好。 顺便说一句,如果我使用img.reformate(-1,

假设我有一个np.数组(图)

我怎样才能把它分成4种作物

[[1,2],    [[3,4],    [[9,10],    [[11,12],
 [5,6]]     [7,8]]     [13,14]]     [15,16]]
我知道的唯一方法是使用循环指定
img[x\u start:x\u end,y\u start:y\u end]
。 但对于大型3D体积而言,这非常耗时。 在某些算法中,NumPy库本身的性能似乎比循环更好。 顺便说一句,如果我使用
img.reformate(-1,2,2)
,我会得到以下矩阵,这不是我想要的:

[[1,2],    [[5,6],    [[9,10],    [[13,14],
 [3,4]]     [7,8]]     [11,12]]     [15,16]]

当然,它不一定是Numpy库,但也可以是cv2或类似的东西,我可以在python中使用它

我希望我正确理解了你的问题:

img=np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16])
out=[np.vsplit(x,2)表示np.hsplit(img,2)中的x]
对于arr1输入输出:
对于arr1中的arr2:
打印(arr2)
打印()
印刷品:

[[12]
[5 6]]
[[ 9 10]
[13 14]]
[[3 4]
[7 8]]
[[11 12]
[15 16]]

要解决您的问题,您可以使用axis,例如使用
np.transpose
np.moveaxis

下面的解决方案可能不是最快的,但它说明了如何使用这些工具

img = np.array([[1,2,3,4],
         [5,6,7,8],
         [9,10,11,12],
         [13,14,15,16]])
img = img.reshape(-1,2,2)
img = np.moveaxis(img, 0, 1)
img = img.reshape(-1,2,2)
输出:

>>> print(img)
[[[ 1  2]
  [ 5  6]]

 [[ 9 10]
  [13 14]]

 [[ 3  4]
  [ 7  8]]

 [[11 12]
  [15 16]]]

您想要的是所谓的滑动窗口视图
NumPy
已经有了一个函数来执行此操作:
NumPy.lib.stride\u tricks.slide\u window\u view
,但该函数不采用自定义的步幅(滑动窗口的步长)。我已经实现了我自己的函数,它提供了这样一个视图(需要最小的内存开销):


另一方面,如果您计划使用所述滑动窗口使用平均内核模糊图像或执行边缘检测或其他操作,则可以使用
scipy.signal.convalve2d
(以及许多其他类似函数)来执行此操作。

谢谢!这正是我想要的!我发现我们可以把out=[np.vsplit(x,2)表示np.hsplit(img,2)]改为out=[np.vsplit(x,size)表示np.hsplit(img,size)],其中size是我想要的裁剪尺寸
>>> print(img)
[[[ 1  2]
  [ 5  6]]

 [[ 9 10]
  [13 14]]

 [[ 3  4]
  [ 7  8]]

 [[11 12]
  [15 16]]]
import numpy as np 
from numpy.lib.stride_tricks import as_strided
from typing import Tuple


def get_sliding_window_2d(x: np.ndarray, width: int, height: int, rowstride: int, colstride: int):
    """
    x: np.array
    width: width of window
    height: height of window
    rowstride: horizontal window step size
    colstride: vertical window step size 
    """
    imgRows, imgCols = x.shape
    u = np.array(x.itemsize)
    return as_strided(x,
        shape=((imgRows-width)//rowstride+1, (imgCols-height)//colstride+1, width, height), 
        strides=u*(imgCols*rowstride, colstride, imgCols, 1)
    )

a = np.arange(4*4).reshape(4,4)+1
for windows in get_sliding_window_2d(a, 2, 2, 2, 2):
    for window in windows:
        print(window, end="\n\n")

#[[1 2]
# [5 6]]
#
#[[3 4]
# [7 8]]
#
#[[ 9 10]
# [13 14]]
#
#[[11 12]
# [15 16]]