Labfans是一个针对大学生、工程师和科研工作者的技术社区。 论坛首页 | 联系我们(Contact Us)
MATLAB爱好者论坛-LabFans.com
返回   MATLAB爱好者论坛-LabFans.com > 其它 > 资料存档
资料存档 资料存档
 
 
主题工具 显示模式
旧 2019-12-14, 20:13   #1
poster
高级会员
 
注册日期: 2019-11-21
帖子: 3,006
声望力: 66
poster 正向着好的方向发展
帖子 我如何在类似于Matlab的blkproc(blockproc)函数的块中高效处理numpy数组

我正在寻找一种有效的方法,用于将图像有效地划分为小区域,分别处理每个区域,然后将每个过程的结果重新组合为一个已处理的图像。 Matlab为此提供了一个名为blkproc的工具(在较新版本的Matlab中由blockproc代替)。

在理想情况下,函数或类也将支持输入矩阵中各部分之间的重叠。在Matlab帮助中,blkproc定义为:
B = blkproc(A,[mn],[mborder nborder],fun,...)

  • A是您的输入矩阵,
  • [mn]是块大小
  • [mborder,nborder]是边界区域的大小(可选)
  • fun是应用于每个块的功能
我拼凑出一种方法,但是它让我感到笨拙,我敢打赌,还有更好的方法。冒着我自己的窘境,这是我的代码:

import numpy as np def segmented_process(M, blk_size=(16,16), overlap=(0,0), fun=None): rows = [] for i in range(0, M.shape[0], blk_size[0]): cols = [] for j in range(0, M.shape[1], blk_size[1]): cols.append(fun(M[i:i+blk_size[0], j:j+blk_size[1]])) rows.append(np.concatenate(cols, axis=1)) return np.concatenate(rows, axis=0) R = np.random.rand(128,128) passthrough = lambda(x):x Rprime = segmented_process(R, blk_size=(16,16), overlap=(0,0), fun=passthrough) np.all(R==Rprime)

回答:

以下是使用块的另一种(无循环)方法的示例:

import numpy as np from numpy.lib.stride_tricks import as_strided as ast A= np.arange(36).reshape(6, 6) print A #[[ 0 1 2 3 4 5] # [ 6 7 8 9 10 11] # ... # [30 31 32 33 34 35]] # 2x2 block view B= ast(A, shape= (3, 3, 2, 2), strides= (48, 8, 24, 4)) print B[1, 1] #[[14 15] # [20 21]] # for preserving original shape B[:, :]= np.dot(B[:, :], np.array([[0, 1], [1, 0]])) print A #[[ 1 0 3 2 5 4] # [ 7 6 9 8 11 10] # ... # [31 30 33 32 35 34]] print B[1, 1] #[[15 14] # [21 20]] # for reducing shape, processing in 3D is enough C= B.reshape(3, 3, -1) print C.sum(-1) #[[ 14 22 30] # [ 62 70 78] # [110 118 126]] 因此,仅尝试简单地将matlab功能复制到numpy并不是所有最佳方法。有时需要“脱帽而出”的思维。

警告
通常,基于跨步技巧的实现可能会 (但不一定需要)遭受一些性能损失。因此,请做好准备以各种方式衡量您的表现。无论如何,明智的做法是首先检查所需的功能(或足够相似,以便轻松适应)是否已全部以numpy或scipy 。

更新
请注意,有没有真正的magic与这里涉及strides ,所以我将提供一个简单的函数来得到一个block_view任何合适的2D numpy -阵列。所以我们开始:

from numpy.lib.stride_tricks import as_strided as ast def block_view(A, block= (3, 3)): """Provide a 2D block view to 2D array. No error checking made. Therefore meaningful (as implemented) only for blocks strictly compatible with the shape of A.""" # simple shape and strides computations may seem at first strange # unless one is able to recognize the 'tuple additions' involved ;-) shape= (A.shape[0]/ block[0], A.shape[1]/ block[1])+ block strides= (block[0]* A.strides[0], block[1]* A.strides[1])+ A.strides return ast(A, shape= shape, strides= strides) if __name__ == '__main__': from numpy import arange A= arange(144).reshape(12, 12) print block_view(A)[0, 0] #[[ 0 1 2] # [12 13 14] # [24 25 26]] print block_view(A, (2, 6))[0, 0] #[[ 0 1 2 3 4 5] # [12 13 14 15 16 17]] print block_view(A, (3, 12))[0, 0] #[[ 0 1 2 3 4 5 6 7 8 9 10 11] # [12 13 14 15 16 17 18 19 20 21 22 23] # [24 25 26 27 28 29 30 31 32 33 34 35]]

更多&回答...
poster 当前离线   回复时引用此帖
 


发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛禁用 表情符号
论坛启用 [IMG] 代码
论坛启用 HTML 代码



所有时间均为北京时间。现在的时间是 02:55


Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.