Работа с изображениями в Python с использованием PIL и проблема с fromarray () - PullRequest
2 голосов
/ 18 марта 2019

Я пишу скрипт для шифрования и дешифрования изображения в python3 с использованием PIL.Здесь я конвертирую изображение в массив numpy, а затем умножаю каждый элемент массива на 10. Теперь я заметил, что функция по умолчанию в PIL fromarray () конвертирует каждый элемент массива в мод 256, если он больше, чем255, поэтому, когда я пытаюсь получить исходное значение матрицы, я не получаю исходное значение.Например, если исходное значение равно 40, то его 10-кратное значение равно 400, поэтому функция fromarray () делает его равным 400 мод 256, что даст 144. Теперь, если я добавлю 256 к 144, у меня будет 400, а затем разделить на 10,дайте мне 40. Но если значение 54, то 10 раз равно 540, а 540 мод 256 равно 28. Теперь, чтобы вернуть исходное значение, мне нужно добавить 256 два раза, что даст мне 540. 540 не единственное число, которое будетдайте мне 28, когда я сделаю мод с 256. Поэтому я никогда не узнаю, когда добавить 256 один раз, а когда два или более.

Вот код:

from PIL import Image
from numpy import * 
from pylab import * 

#encryption

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

img = array(Image.open('image.jpeg').convert('L'))
a,b = img.shape
print(img)
print((a,b))
tup = a,b

for i in range (0, tup[0]):
    for j in range (0, tup[1]):
        img[i][j]= img[i][j]*10 #converting every element of the original array to its 10times

print(img)
imgOut = Image.fromarray(img)
imgOut.show()
imgOut.save('img.jpeg')

#decryption

img2 = (Image.open('img.jpeg'))
img2.show()

img3 = array(Image.open('img.jpeg'))
print(img3)
a1,b1 = img3.shape
print((a1,b1))
tup1 = a1,b1

for i1 in range (0, tup1[0]):
    for j1 in range (0, tup1[1]):
        img3[i1][j1]= ((img3[i1][j1])/10) #reverse of encryption
print(img3)
imgOut1 = Image.fromarray(img3)
imgOut1.show()

Теперь, когда функция, делающая свои элементы модом 256, я не могу получить исходное значение из значения мода.Как я могу получить исходное значение. Существуют ли другие методы для преобразования матрицы в изображение и наоборот, которые не сделают его модом из любого числа по умолчанию.

Теперь я не знаю, как справиться с этой проблемой.Любая помощь будет принята с благодарностью. Спасибо.

1 Ответ

1 голос
/ 25 марта 2019

Это не правильный способ сделать это. Там нет никакого способа, которым вы можете иметь фактическое значение. После изменения значений на mod of 256 вы не сможете вернуть предыдущее значение. Поскольку вы читаете изображение как 8bit depth JPEG, вы не можете иметь значение больше 255 в numpy array, поскольку нам нужно более 8 бит для хранения значения, которое больше 255 в десятичной системе счисления. Таким образом, вы можете прочитать изображение как изображение глубиной 8 бит, а затем преобразовать numpy.ndarray изображения в 16 или 32 бита, как хотите. Вы можете сделать это с помощью img_array.astype(numpy.uint16) Или же img_array.astype(numpy.uint32) Вы можете проверить тип, используя print(img_array.dtype()) Если вы преобразуете массив numpy в uint16, то самое большое значение, которое вы можете иметь в массиве, равно 2^16-1, а для uint32 - 2^32-1.

Теперь вы можете сохранить массив, используя imageio, который может считать запись изображения как 16-битную глубину.

`import imageio as io
 img_array = io.imread('16bit.png')
 io.imwrite('new16bit.png', img_array)`

Используйте .png в качестве без потерь и может хранить 16-битные данные. PIL всегда преобразует 16-битный или 32-битный массив в 8-битный.

...