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

时间:2016-12-07 21:29:22

标签: numpy scipy scikit-image

我正在使用sci-kit图片中的mean filter。但是,它似乎将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

但是,根据文档,返回类型应与输入类型相同。这是怎么回事?

1 个答案:

答案 0 :(得分:3)

Scikit-image的rank过滤器仅针对uint8uint16数据类型定义。这就是为什么它转换为uint8,即获得结果的类型。例如。 documentation rank.mean,其中说:

  

图像:二维数组(uint8,uint16)

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

相反,您可以使用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)

注意:以上称为separable convolution。它的工作原理是将图像与两个1维滤波器进行卷积,首先在y轴上,然后在x轴上(顺序无关紧要)。尽管它看起来很丑陋(因为你必须将图像卷积两次),但当你的内核(滤波器)可分离时,运行两个1维卷积比运行单个2D卷积快几个数量级。 Scipy的uniform_filter在幕后做了这件事。它每轴调用一次uniform_filter1d