[英]Extracting 2d patches from 3d arrays
scikit-learn 的extract_patches_2d
可用于将 2D 图像重塑为补丁集合。 extract_patches
是使用 NumPy 的as_strided
的通用形式。
import numpy as np
from sklearn.feature_extraction import image
ex = np.arange(3 * 3).reshape(3, 3)
image.extract_patches_2d(ex, patch_size=(2, 2))
[[[0 1]
[3 4]]
[[1 2]
[4 5]]
[[3 4]
[6 7]]
[[4 5]
[7 8]]]
我有一个三维数组a
并且想从每个“最里面”的二维数组中提取二维补丁,然后找到每个二维补丁的(轴不可知)平均值。
a = np.arange(2 * 3 * 3).reshape(2, 3, 3)
在这种情况下,我实际上想首先在每个 (3, 3) 内部数组上调用extract_patches_2d
。
patches = np.array([image.extract_patches_2d(i, patch_size=(2, 2)) for i in a])
然后找到每个最里面的二维数组(每个补丁)的平均值:
means = patches.reshape(*patches.shape[:-2], -1).mean(axis=-1)
print(means)
[[ 2. 3. 5. 6.]
[ 11. 12. 14. 15.]]
如何矢量化它并摆脱上面的 for 循环? 这里重要的是, means
的第一个维度的大小等于a
的第一个维度的大小。
您可以使用scikit-image 作为view_as_windows
将这些patches
作为输入数组的view
-
from skimage.util.shape import view_as_windows
size = 2 # patch size
patches = view_as_windows(a, (1,size,size))[...,0,:,:]
这为我们提供了一个5D
数组作为patches
,我们可以使用沿最后两个轴的mean
减少来进行3D
输出 -
out = patches.mean((-2,-1))
如果最终输出需要作为2D
输出,请重塑以合并最后两个轴 -
out.reshape(a.shape[0],-1)
这也可以利用sklearn
的extract_patches
:
def inner_means(arr_3d, patch_size):
"""Axis-agnostic mean of each 2d patch.
Maintains the first dimension of `arr_3d`.
patch_size: tuple
Same syntax as the parameter passed to extract_patches_2d
"""
shape = (1,) + patch_size
patches = image.extract_patches(arr_3d, shape)[..., 0, :, :].mean((-2, -1))
return patches.reshape(*patches.shape[:-2], -1)
a = np.arange(2 * 3 * 3).reshape(2, 3, 3)
print(inner_means(a, patch_size=(2, 2)))
[[ 2. 3. 5. 6.]
[ 11. 12. 14. 15.]]
或者,为了直接获得块状平均值,我们可以使用 Scipy 的卷积工具之一。 所以使用fftconvolve
-
from scipy.signal import fftconvolve
out = fftconvolve(a, np.ones((1,size,size)),mode='valid')/size**2
或者在没有除法的情况下使用scipy.signal.convolve
或scipy.ndimage.filters.uniform_filter
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.