Ответ 1
Я нахожу правильный сюжет гораздо более художественным...
matplotlib
довольно сложна, когда дело доходит до интерпретации изображений. Это примерно так:
-
если изображение представляет собой массив NxM любого типа, оно интерпретируется через colormap (автомасштабирование, если не указано иное). (В принципе, если массив является массивом
/li >float
, масштабированным до 0..1, его следует интерпретировать как изображение в градациях серого. Это то, что говорит документация, но на практике этого не происходит.) -
если изображение представляет собой массив NxMx3
float
, компоненты RGB интерпретируются как компоненты RGB между 0..1. Если значения вне этого диапазона, они берутся с положительным модулем 1, то есть 1,2 → 0,2, -1,7 → 0,3 и т.д. -
если изображение представляет собой массив NxMx3
uint8
, оно интерпретируется как стандартное изображение (компоненты 0..255) -
если изображение NxMx4, интерпретация имеет значение выше, но четвертым компонентом является непрозрачность (альфа)
Итак, если вы даете matplotlib
массив целых чисел NxMx3, отличный от uint8
или float
, результаты не определены. Однако, глядя на исходный код, можно понять нечетное поведение:
if A.dtype != np.uint8:
A = (255*A).astype(np.uint8)
где A
- массив изображений. Итак, если вы дадите uint16
значения 0, 1, 2, 3, 4..., вы получите 0, 255, 254, 253,... Да, это будет выглядеть очень странно. (ИМХО, интерпретация может быть немного более интуитивной, но так оно и делается.)
В этом случае самым простым решением является разделение массива на 65535. Затем изображение должно быть таким, как ожидалось. Кроме того, если исходное изображение действительно линейно, вам необходимо выполнить обратную гамма-коррекцию:
img1_corr = (img1 / 65535.)**(1/2.2)
В противном случае ваши средние тона будут слишком темными.