Я также принял imageio, но я нашел следующие механизмы, полезные для предварительной и последующей обработки:
import imageio
import numpy as np
def imload(*a, **k):
i = imageio.imread(*a, **k)
i = i.transpose((1, 0, 2)) # x and y are mixed up for some reason...
i = np.flip(i, 1) # make coordinate system right-handed!!!!!!
return i/255
def imsave(i, url, *a, **k):
# Original order of arguments was counterintuitive. It should
# read verbally "Save the image to the URL" — not "Save to the
# URL the image."
i = np.flip(i, 1)
i = i.transpose((1, 0, 2))
i *= 255
i = i.round()
i = np.maximum(i, 0)
i = np.minimum(i, 255)
i = np.asarray(i, dtype=np.uint8)
imageio.imwrite(url, i, *a, **k)
Смысл в том, что я использую numpy для обработки изображений, а не только для их отображения. Для этого uint8s неудобен, поэтому я конвертирую в значения с плавающей запятой в диапазоне от 0 до 1.
При сохранении изображений я заметил, что мне пришлось самому обрезать значения, выходящие за пределы диапазона, иначе у меня получился действительно серый вывод. (Вывод серого был результатом сжатия изображения во всем диапазоне, который был за пределами [0, 256), до значений, которые были внутри диапазона.)
Была еще пара странностей, о которых я упоминал в комментариях.