我正在使用 mean filter来自 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
过滤器仅针对 uint8
定义和 uint16
数据类型。这就是它转换为 uint8
的原因。 ,您得到结果的类型。例如。 documentation rank.mean ,它说:
image : 2-D array (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 .它的工作原理是将图像与两个一维过滤器进行卷积,首先在
y
中。轴然后越过 x
轴(顺序无关紧要)。尽管看起来很难看(因为您必须对图像进行两次卷积),但当您的内核(过滤器)是可分离的时,运行两个一维卷积比运行单个二维卷积要快几个数量级。 Scipy's uniform_filter
在幕后这样做。每个轴调用一次到 uniform_filter1d
.
关于numpy - scikit-image:平均过滤器更改 dtype,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41027708/