python - 具有模式功能的 block 减少(下采样)3D阵列

标签 python numpy scikit-image downsampling

我想通过获取原始值的最频繁值(模式)来对 3d 数组进行下采样。经过一番研究,我在skimage 库中找到了block_reduce 函数。例如,如果我想取 block 的平均值,我可以很容易地做到:

from skimage.measure import block_reduce
image = np.arange(4*4*4).reshape(4, 4, 4)
new_image = block_reduce(image, block_size=(2,2,2), func=np.mean, cval=np.mean(grades))

在我的例子中,我想将 func 参数传递给模式函数。但是,numpy 没有模式功能。根据文档,传递的函数应该接受“axis”作为参数。我尝试了一些解决方法,例如编写自己的函数并结合 np.uniquenp.argmax,以及传递 scipy.stats.mode作为功​​能。他们都失败了。

我写了一些嵌套的 for 循环来执行此操作,但是对于大型数组来说它太慢了。是否有捷径可寻?我不一定需要使用 sci-kit 图片库。

提前谢谢你。

最佳答案

让我们假设输入图像形状可以被 block_size 整除,即相应的形状尺寸可以被 block_size 的每个尺寸参数整除。

因此,作为预处理,我们需要从输入的 image 中提取 block ,就像这样 -

def blockify(image, block_size):
    shp = image.shape
    out_shp = [s//b for s,b in zip(shp, block_size)]
    reshape_shp = np.c_[out_shp,block_size].ravel()
    nC = np.prod(block_size)
    return image.reshape(reshape_shp).transpose(0,2,4,1,3,5).reshape(-1,nC)

接下来,对于我们的 mode 查找的特定情况,我们将使用 bincount2D_vectorized连同 argmax -

# https://stackoverflow.com/a/46256361/ @Divakar
def bincount2D_vectorized(a):    
    N = a.max()+1
    a_offs = a + np.arange(a.shape[0])[:,None]*N
    return np.bincount(a_offs.ravel(), minlength=a.shape[0]*N).reshape(-1,N)

out = bincount2D_vectorized(blockify(image, block_size=(2,2,2))).argmax(1)

或者,我们可以使用 n-dim mode -

out = mode(blockify(image, block_size=(2,2,2)), axis=1)[0]

最后,如果可除性的初始假设不成立,我们需要使用适当的填充值进行填充。同样,我们可以使用 np.pad,作为 blockify 方法的一部分。

关于python - 具有模式功能的 block 减少(下采样)3D阵列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62567983/

相关文章:

python - 元素大小不均匀的时间序列

python - 按日期时间对象对 numpy 数组进行排序

python:如何更改skimage调整大小的输出形状

python - 在pymongo中查询 "like"

python - 在格式化之前连接两个字符串时,%s 格式先于 + 运算符

python - 多幅图像和一幅基本图像之间的欧氏距离

python - 如何用蓝色为 RGB 图像着色?

python - 认证用户Django取决于用户

python - cv2.error (-215 :Assertion failed) reader. ptr != NULL 函数 cvDrawContours

python - 从多 channel 图像中提取 channel 名称