为什么skimage.color.rgb2gray在不同设备上的行为不同?

时间:2019-01-12 19:17:43

标签: python scikit-image

我在 skimage.color.rgb2gray 方法上遇到了一些麻烦。我正在使用它通过Python3程序来转换图像(使用Paint在白色画布上绘制的一些简单的黑线),这是这样的:

import matplotlib.image as mpimg
from skimage import color

img = mpimg.imread('Image (1).png')
gray = color.rgb2gray(img)

我发现它在两个不同的设备上返回不同的数组。

第一个是Raspberry Pi 3 Model B(操作系统:Raspbian GNU / Linux 8(jessie)),它会返回它,

[[0.99999994 0.99999994 0.99999994 ... 0.99999994 0.99999994 0.99999994]
[0.99999994 0.99999994 0.99999994 ... 0.99999994 0.99999994 0.99999994] 
[0.99999994 0.99999994 0.99999994 ... 0.99999994 0.99999994 0.99999994]
...
[0.99999994 0.99999994 0.99999994 ... 0.99999994 0.99999994 0.99999994]
[0.99999994 0.99999994 0.99999994 ... 0.99999994 0.99999994 0.99999994]
[0.99999994 0.99999994 0.99999994 ... 0.99999994 0.99999994 0.99999994]]

这是错误的,因为数字应该是1.0,所以是白色。

第二个是Windows 10 Home(1803版),一切运行顺利:

[[1. 1. 1. ... 1. 1. 1.]
[1. 1. 1. ... 1. 1. 1.]
[1. 1. 1. ... 1. 1. 1.]
...
[1. 1. 1. ... 1. 1. 1.]
[1. 1. 1. ... 1. 1. 1.]
[1. 1. 1. ... 1. 1. 1.]]

有人可以解释一下原因吗?提前致谢! 如果需要其他详细信息,请告诉我。

1 个答案:

答案 0 :(得分:0)

如您对问题的评论中所述,计算机中的浮点(即非整数)计算不准确。证明这一点的标准方法是验证0.1 + 0.2 == 0.3返回False。在处理器之间和数值库之间(可能以不同的顺序执行操作),如何的近似情况有所不同。您可以在此处了解更多信息:http://0.30000000000000004.com

除了最小化已完成的操作数量之外,我认为没有其他简便的方法可以解决此问题。在您的情况下,您的图像是png,可以直接是灰度图像,因此您可以从一开始就将图像另存为灰度图像,而无需进行转换。另外,如果您知道您的图像只是黑白或灰度(即没有颜色信息,除了保存为RGB图像外),则每个通道中的内容都相同,您可以编写:

from skimage.util import img_as_float
from skimage.io import imread

image = imread('Image (1).png')  # typically uint8 values in [0, 255]
gray = image[..., 0]  # 0th channel, red
gray_float = img_as_float(gray)  # optional, get floats in [0, 1]

有关最后一次转换的更多信息,请参见scikit-image文档中的以下页面:http://scikit-image.org/docs/dev/user_guide/data_types.html