我正在寻找一种有效的方法,将图像分割成小区域,分别处理每个区域,然后将每个处理的结果重新组合成单个处理的图像。Matlab有一个称为blkproc的工具(在新版Matlab中被^{
在理想情况下,函数或类也会支持输入矩阵中各部分之间的重叠。在Matlab帮助中,blkproc定义为:
B = blkproc(A,[m n],[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)
我接受了两种输入,以及我最初的方法,并比较了结果。正如@eat正确指出的,结果取决于输入数据的性质。令人惊讶的是,在少数情况下,连接优于视图处理。每种方法都有一个优点。这是我的基准代码:
结果如下:
请注意,对于较小的块大小,分段步幅方法的优势是3-4倍。只有在大的块大小(128 x 128)和非常大的矩阵(2048 x 2048和更大)下,视图处理方法才能获胜,而且只占很小的百分比。根据烘烤的结果,看起来@eat得到了复选标记!谢谢你们两位的好榜样!
下面是使用块的不同(无循环)方法的一些示例:
因此,简单地将
matlab
功能复制到numpy
并不一定是最好的方法。有时候需要一个“脱帽”的想法。警告:
一般来说,基于跨步技巧的实现可能会受到一些性能损失(但不需要)。所以要准备好用各种方法来衡量你的表现。在任何情况下,明智的做法是首先检查所需的功能(或类似的功能,以便轻松适应)是否已经在
numpy
或scipy
中实现。更新:
请注意,这里没有真正的
magic
与strides
相关,因此我将提供一个简单的函数来获取任何合适的2Dnumpy
数组的block_view
。所以我们来:按切片/视图处理。连接非常昂贵。
相关问题 更多 >
编程相关推荐