首页 > 解决方案 > python中的中位数下采样

问题描述

我想使用中值滤波器对图像进行下采样。乍一看,with中的block_reduce方法似乎很合适。然而,我得到的印象是一次应用一个轴,而我希望中值滤波器一次应用于整个块 - 对于非平凡的输入,结果是不一样的。skimagefunc=numpy.medianblock_reducefunc

一个最小的演示示例是这样的:

from skimage.measure import block_reduce
import numpy as np

image = np.array([[4, 6, 6, 2],
 [6, 7, 9, 9],
 [3, 0, 9, 0],
 [0, 6, 6, 4]])

expected = np.array([[np.median(image[0:2,0:2]), np.median(image[0:2,2:4])],
            [np.median(image[2:4,0:2]), np.median(image[2:4,2:4])]])

actual = block_reduce(image, (2,2), func=np.median)

assert np.array_equal(expected, actual)

最后一个断言失败,因为中值滤波器没有按我预期的方式应用。

您能否建议使用中值滤波器对图像进行下采样的其他方法?

标签: pythonscikit-image

解决方案


这是一些解决您的特定问题的技巧。

def clever_func(block, axis):
    # axis unused on purpose
    if len(block.shape) == 4:
        return np.median(block, axis=[2, 3])
    else:
        return block

actual = block_reduce(image, (2,2), func=clever_func)

本质上,参数functoblock_reducefunc(out, axis=-1)在代码(source)中被调用。我没有调用 ,而是劫持了这个,以便使用正确的参数numpy.median调用中位数。axis

在您的示例中,block.shape(2, 2, 2, 2)在第一次调用中,然后(2, 2, 2)在第二次调用clever_func. 我只在第一次调用 ( if len(block.shape) == 4) 时使用 np.median,而在第二次调用时没有使用。

这不是一个很好的解决方案。


推荐阅读