Image.fromarray () делает каждый элемент в матричном моде 256

Из-за точного формата сериализованного файла добавление действительно испортит его. Вы должны записать все объекты в файл как часть одного и того же потока, иначе он будет сбой при чтении метаданных потока, когда он ожидает объект.

Вы можете прочитать спецификацию Serialization Specification для более подробной информации или (проще) прочитать эту нить , где Roedy Green говорит в основном то, что я только что сказал.

-1
задан Cris Luengo 18 March 2019 в 12:58
поделиться

3 ответа

Есть несколько проблем с тем, что вы пытаетесь сделать здесь.

Изображения 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. Хотя это было бы операцией с потерями, и у вас не было бы никакого способа возвращение незафиксированных значений.

0
ответ дан AKX 18 March 2019 в 12:58
поделиться

Прежде всего, PIL поддерживает только 8-битные изображения на канал - хотя Подушка (форк PIL) поддерживает гораздо больше форматов , включая более высокую битовую глубину. Формат JPEG определяется только как 8-битный на канал.

Следовательно, вызов Image.open() для JPEG в PIL вернет 8-битный массив, поэтому любые операции с отдельными пикселями будут выполняться как эквивалент арифметики uint8_t в вспомогательном представлении. Поскольку максимальное значение в uint8_t равно 256, вся ваша арифметика обязательно должна быть по модулю 256.

Если вы хотите избежать этого, вам нужно преобразовать представление в более высокую битовую глубину, такую ​​как 16bpp или 32bpp. Вы можете сделать это с помощью кода NumPy, например:

img16 = np.array(img, dtype=np.uint16)
# or
img32 = np.array(img, dtype=np.uint32)

, который даст вам желаемую расширенную точность.

Однако - ваш пример кода показывает, что вы пытаетесь зашифровать и расшифровать данные изображения. В этом случае вы действительно хотите использовать арифметику по модулю! Вам просто нужно больше изучить реальные алгоритмы шифрования.

0
ответ дан gavinb 18 March 2019 в 12:58
поделиться

Поскольку ни один из ответов не помог мне так сильно, и я решил проблему, я хотел бы дать ответ, надеясь, что однажды он кому-нибудь поможет. Здесь ключи (3, 25777) и (16971,25777). Рабочий код выглядит следующим образом:

from PIL import Image
import numpy as np 

#encryption
img1 = (Image.open('image.jpeg').convert('L')) 
img1.show()

img = array((Image.open('image.jpeg').convert('L'))) 
img16 = np.array(img, dtype=np.uint32)
a,b = img.shape
print('\n\nOriginal image: ')
print(img16)
print((a,b))
tup = a,b

for i in range (0, tup[0]):
    for j in range (0, tup[1]):
        x = img16[i][j] 
        x = (pow(x,3)%25777)
        img16[i][j] = x
print('\n\nEncrypted image: ')
print(img16)
imgOut = Image.fromarray(img16)
imgOut.show()

#decryption

img3_16 = img16
img3_16 = np.array(img, dtype=np.uint32)
print('\n\nEncrypted image: ')
print(img3_16)
a1,b1 = img3_16.shape
print((a1,b1))
tup1 = a1,b1

for i1 in range (0, tup1[0]):
     for j1 in range (0, tup1[1]):
         x1 = img3_16[i1][j1] 
         x1 = (pow(x,16971)%25777)  
         img3_16[i][j] = x1
print('\n\nDecrypted image: ')
print(img3_16)
imgOut1 = Image.fromarray(img3_16)y
imgOut1.show()

Не стесняйтесь указывать на неисправности. Спасибо.

0
ответ дан Sandipan 18 March 2019 в 12:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: