Есть несколько проблем с тем, что вы пытаетесь сделать здесь.
Изображения PIL либо 8-битные на канал, либо 16-битные на канал (насколько мне известно).Когда вы загружаете JPEG, он загружается как 8 бит на канал, поэтому базовый тип данных представляет собой 8-разрядное целое число без знака, то есть диапазон 0..255.Операции, которые будут переполнять или пропускать эту обертку диапазона, что похоже на поведение модуля, которое вы видите.
Вы можете преобразовать 8-битное изображение PIL в массив с плавающей запятой с помощью np.array(img).astype('float32')
и затем нормализовать этодо 0..1 путем деления на 255.
В этот момент у вас есть неквантованные числа с плавающей запятой, которые вы можете свободно изменять по своему усмотрению.
Однако, вам все равно нужно сохранитьПолученное изображение, после чего у вас снова возникает проблема с форматированием.Я полагаю, что файлы TIFF и некоторые форматы изображений HDR поддерживают данные с плавающей запятой, но если вы хотите что-то, что будет широко читаемым, вы, вероятно, предпочтете PNG или JPEG.
Для случая использования шифрования JPEG не годитсявыбор, поскольку они всегда по своей природе с потерями, и вы, скорее всего, не получите обратно одни и те же данные.
PNG могут иметь 8 или 16 бит на канал, но тем не менее, вы получитепроблема сжатия практически бесконечного «динамического диапазона» пикселей (скажем, вы умножили все на тысячу!) до 0..255 или 0..65535.
Очевидный способ сделать эточтобы найти максимальное значение в изображении (np.max(...)
), разделить все на него (так что теперь вы вернулись к 0..1), затем умножить на максимальное значение формата данных изображения ... так что спросто умножив «шифр», как вы описали, вы по сути получите то же изображение обратно.
Другим способом было бы обрезать бесконечный диапазон при допустимых значениях, то есть все, что ниже нуля, равно нулю, всескажем, это 65535. Хотя это была бы операция с потерями, и у вас не было бы возможности вернуть незафиксированные значения обратно.