Почему skimage.color.rgb2gray на разных устройствах ведет себя по-разному? - PullRequest
0 голосов
/ 12 января 2019

У меня проблемы с skimage.color.rgb2gray . Я использую его, чтобы превратить изображение (некоторые простые черные линии, нарисованные на белом холсте с помощью Paint) с помощью программы Python3, которая выглядит так:

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 голосов
/ 13 января 2019

Как упоминалось в комментариях к вашему вопросу, вычисления с плавающей запятой (то есть нецелые) в компьютерах не являются точными. Стандартный способ продемонстрировать это - проверить, что 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...