Преобразование 2-мерной матрицы rgb в изображение PNG с Python 3.6 - PullRequest
1 голос
/ 02 октября 2019

Мне нужно преобразовать 2-мерную 24-битную rgb-матрицу с Python 3.6

[[rr11gg11bb11, rr12gg12bb12,..  ..,rr1mgg1mbb1m],
.
.
 [rri1gg11bb11, rr12ggi2bb12,..  ..,rr1mgg1mbb1m]
.
.
 [rrn1ggn1bbn1, rrn2ggn2bbn2,.. ..,rrmnggmnbbmn]]

в изображение формата tif, png и jpg.

У меня также естьматрица в виде файла

image.bin.

Из этого двоичного файла я могу получить изображение с помощью программы просмотра пикселей RAW:

http://rawpixels.net/ 

Я нашел библиотеку PIL,но я не нашел никакого способа построить объект изображения из этих данных. Как я могу это сделать? Я использую Python 3.6.

Теперь я попробовал следующее:

im = Image.frombuffer('RGB', (self.width, self.height), self.matrix, 'raw', 
'RGB', 0, 1)              
logger.info("image object created.")
im.save('result.png')
logger.info("image saved as result.png")

Но я получаю сообщение:

TypeError: a bytes-like object is required, not 'list'

Теперь я узнал, чтоЯ должен преобразовать объект в байтовый массив:

 npm = np.array(self.matrix)
 arr = bytearray(npm)
 print(arr)
 im = Image.frombuffer('RGB', (self.width, self.height), arr, 'raw', 
'RGB', 0, 1)        

Преобразование просто работает, когда я использую 'L' или 'RGBA', но не с 'RGB'. Странно, но в этом случае он отказывается от объекта bytearray.

1 Ответ

2 голосов
/ 02 октября 2019

Обновленный ответ

Итак, по сути, у вас нет массива Numpy, но у вас есть список списков, в котором каждый элемент представляет собой single 24-битное число, представляющее триплет RGB RGB888.

Итак, я могу сделать представление вашего списка следующим образом:

f=[ 
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF],
[0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x000000,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF]
] 

Итак, я могу превратить его в массив Numpy из uint32элементы вроде этого:

na = np.array(f).astype(np.uint32) 

А затем создайте массив RGB, который PIL будет любить использовать:

h,w = 5,10
RGB=np.zeros((h,w,3),dtype=np.uint8)

Тогда мне просто нужно сдвинуть и скопировать триплеты в нужные места:

RGB[:,:,0] = na>>16            # Take red from top
RGB[:,:,1] = (na>>8) & 0xff    # Take green from middle
RGB[:,:,2] = na & 0xff         # Take blue from bottom

Теперь я могу сделать изображение PIL из этого массива RGB и сохранить его на диск:

pIm = Image.fromarray(RGB).save('result.png')

Оригинальный ответ

Давайте создадимфайл тестовых данных с ImageMagick . Сначала как PNG, просто чтобы вы могли видеть это:

magick -size 640x480 gradient:magenta-yellow image.png

enter image description here

И теперь снова то же самое, но на этот раз для соответствия RGB888Ваш файл:

magick -size 640x480 gradient:magenta-yellow -depth 8 rgb:image.bin

Сейчас:

from PIL import Image

# Open the file and read contents into "data"
with open('image.bin','rb') as f: 
    data = f.read() 

# Convert that into PIL Image
im = Image.frombuffer('RGB', (640, 480), data, 'raw', 'RGB', 0, 1)

# Save
im.save('result.png')

Вы также можете позволить Numpy прочитать файл и затем преобразовать результат в изображение PIL:

import numpy as np

im = Image.fromarray(np.fromfile('image.bin',dtype=np.uint8).reshape(480,640,3))

Если вы хотите проверить, что ваш двоичный файл действительно содержит то, что, как вы думаете, он содержит, вы также можете преобразовать его в PNG с помощью ImageMagick , чтобы проверить его. Допустим, вы считаете, что файл имеет ширину 640 пикселей и высоту 480 пикселей, а RGB888 можно попросить ImageMagick превратить его в PNG с:

magick -depth 8 -size 640x480 RGB:<YOURFILENAME> image.png

Или, если вы считаете, что этоодно 16-битное одноканальное серое изображение с 128-байтовым заголовком, которое вы хотите игнорировать:

magick -depth 16 -size 640x480+128 GRAY:<YOURFILENAME> image.png

Ключевые слова : необработанное, необработанное изображение, двоичный файл, изображение, обработка изображения, Python, ImageMagick, конвертировать.

...