[英]how crop an image evenly without loop
Suppose I have an np.array(image)假设我有一个 np.array(image)
img = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]
How can I divide this in to 4 crops?我怎样才能把它分成4种作物?
[[1,2], [[3,4], [[9,10], [[11,12],
[5,6]] [7,8]] [13,14]] [15,16]]
The only way I know is to use loop to specify the img[x_start:x_end,y_start:y_end]
.我知道的唯一方法是使用循环来指定
img[x_start:x_end,y_start:y_end]
。 But this is very time-consuming when it comes to a large 3D Volume.但是对于较大的 3D 卷,这是非常耗时的。 NumPy library seems to perform better by itself than the loop in some algorithms.
在某些算法中,NumPy 库本身似乎比循环执行得更好。 Btw, if I use
img.reshape(-1,2,2)
, I get the following matrix, which is not what I want:顺便说一句,如果我使用
img.reshape(-1,2,2)
,我会得到以下矩阵,这不是我想要的:
[[1,2], [[5,6], [[9,10], [[13,14],
[3,4]] [7,8]] [11,12]] [15,16]]
Of course, it doesn't have to be Numpy library but can also cv2 or something like that which I can use in python当然,它不必是 Numpy 库,但也可以是 cv2 或类似的东西,我可以在 python 中使用
I hope I've undersdoot your question right:我希望我正确理解了您的问题:
img = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
out = [np.vsplit(x, 2) for x in np.hsplit(img, 2)]
for arr1 in out:
for arr2 in arr1:
print(arr2)
print()
Prints:印刷:
[[1 2]
[5 6]]
[[ 9 10]
[13 14]]
[[3 4]
[7 8]]
[[11 12]
[15 16]]
To solve your problem you can play with axis using np.transpose
or np.moveaxis
for example.为了解决您的问题,您可以使用例如
np.transpose
或np.moveaxis
来玩轴。
The following solution is probably not the fastest but it illustrates what you can do with these tools.以下解决方案可能不是最快的,但它说明了您可以使用这些工具做什么。
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)
Output: Output:
>>> print(img)
[[[ 1 2]
[ 5 6]]
[[ 9 10]
[13 14]]
[[ 3 4]
[ 7 8]]
[[11 12]
[15 16]]]
What you want to have is called a sliding window view .您想要的称为滑动 window 视图。
NumPy
already has a function to do this: numpy.lib.stride_tricks.sliding_window_view
, but the function does not take custom strides (step size of your sliding window). NumPy
already has a function to do this: numpy.lib.stride_tricks.sliding_window_view
, but the function does not take custom strides (step size of your sliding window). I have implemented my own function which gives such a view (requiring minimal memory overhead):我已经实现了自己的 function ,它给出了这样的视图(需要最小的 memory 开销):
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]]
On a related note, if you plan to use said sliding windows to blur images using a mean kernel or do edge detection or something, you can use scipy.signal.convolve2d
(and many other similar functions) to do it.在相关的说明中,如果您打算使用上述滑动 windows 来模糊图像,使用平均 kernel 或进行边缘检测或其他操作,您可以使用
scipy.signal.convolve2d
(和许多其他类似功能)来进行卷积。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.