我正在使用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
但是,根据文档,返回类型应与输入类型相同。这是怎么回事?
答案 0 :(得分:3)
Scikit-image的rank
过滤器仅针对uint8
和uint16
数据类型定义。这就是为什么它转换为uint8
,即获得结果的类型。例如。 documentation rank.mean,其中说:
图像:二维数组(uint8,uint16)
因此,如果您输入uint8
或uint16
,则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
。