scikit-image:平均过滤器更改dtype



我正在使用sci-kit图像中的平均过滤器。但是,它似乎将浮点图像的dtype更改为uint8,这再次将其传递给其他过滤器功能时会导致问题。

作为插图,请考虑以下代码。

import numpy as np
from skimage import filters
from skimage.morphology import square
def mean_filter(img):
    selem = square(3)
    print(img.dtype)
    print(img.max(), img.min())
    fi =  filters.rank.mean(img, selem=selem)
    print(fi.dtype)
    print(fi.max(), fi.min())
    return fi
arr = np.array([[.1, .2, .3], 
                [.4, .5, .6],
                [.7, .8, .9]], dtype='float64')
m = mean_filter(arr) 

给出以下输出。

float64
0.9 0.1
uint8
178 76

但是,根据文档,返回类型应与输入类型相同。这里发生了什么?

Scikit-Image的rank过滤器仅针对uint8uint16数据类型定义。这就是为什么它将转换为uint8的原因,即您获得结果的类型。例如。文档等级。表示:

图像:2-D数组(UINT8,UINT16)

因此,如果您输入uint8uint16,则会在结果中保留该数据类型。否则,它将尝试将您的图像转换为引擎盖下的一个。

您可以做的是使用scipy

>>> from scipy.ndimage import uniform_filter
>>> size = 3
>>> result = uniform_filter(arr, size)

或者如果您喜欢创建自己的过滤器:

>>> from scipy.ndimage import convolve1d
>>> size = 3
>>> kernel = np.ones(size, arr.dtype) / size
>>> result = convolve1d(convolve1d(arr, kernel, axis=0), kernel, axis=1)

注意:以上称为可分离卷积。它通过将图像与两个一维过滤器进行卷积,首先在y轴上,然后在x轴上(顺序无关紧要)。尽管它看起来很丑陋(因为您必须两次卷动图像),但是当您的内核(过滤器)是可分离的时,运行两个一维卷积的数量级比运行单个2D卷积快。Scipy的uniform_filter在场景后面做到这一点。它每轴一次调用uniform_filter1d

最新更新