Создать изображение из данных пикселей uint8 RGB

Я пытаюсь создать библиотеку, связанную с данными пикселей RGB, но не могу правильно сохранить данные изображения.

Это мое выходное изображение. Это мой код:

пиксельный менеджер.py

from PIL import Image
import numpy as np

class MakeImgFromPixelRGB:
    def createIMG(PixelArray: list, ImgName: str, SaveImgAsFile: bool):
        # Convert the pixels into an array using numpy
        array = np.array(PixelArray, dtype=np.uint8)
        if SaveImgAsFile == True:
            new_image = Image.fromarray(array)
            new_image.save(ImgName)
class getPixelsFromIMG:
    def __init__(self, ImagePath):
        im = Image.open(ImagePath, 'r')
        width, height = im.size
        pixel_values = list(im.getdata())
        self.output = pixel_values

test.py

import pixelmanager

a = pixelmanager.getPixelsFromIMG(ImagePath = "download.jpg")

pixelmanager.MakeImgFromPixelRGB.createIMG(a.output, "output.png", True)

with open("output.txt", "w") as f:
    for s in a.output:
        f.write(str(s) + "," + "\n")

Я пытался уменьшить масштаб изображения в Paint.net, а также пытался изменить размер uint.

Непонятно, почему этот результат оказался не таким, как вы ожидали. Что в этом неправильного?

Mark Ransom 19.08.2024 19:43

Линия — это выходное изображение. Я пытался установить данные советского флага, которые я получил от другой функции, которая получает данные пикселей.

Kssonety 20.08.2024 21:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Обрабатывать изображения как списки пикселей Python, как правило, не лучшая идея, поскольку это медленно и подвержено ошибкам. В общем, вы хотите использовать функции PIL, которые закодированы в C и работают с типами PIL Image, или Numpy или OpenCV, которые сильно векторизованы/оптимизированы и работают с массивами Numpy.

В любом случае, если вы действительно хотите иметь дело со списками (а это не так), вам нужно помнить, что когда вы вызываете Image.getdata() для JPEG, вы получаете плоский список кортежей RGB. Итак, если ваше изображение имеет размер 640x480 пикселей и вы делаете это:

im = Image.open('image.jpg')
px = list(im.getdata())

вы получите список из 307 200 записей, каждая из которых представляет собой кортеж RGB. НО ваш список больше не знает высоту и ширину изображения. Итак, когда вы впоследствии сделаете:

array = np.array(PixelArray, dtype=np.uint8)

ваш массив теперь имеет форму (307200,3) вместо (480,640,3) - ооооо, вы получаете длинную строку пикселей в выходном изображении.

Если вы настаиваете на использовании списков, вам нужно будет сохранить высоту и ширину исходного изображения, поэтому вы можете сделать:

array = np.array(PixelArray, dtype=np.uint8).reshape(h,w,3)

Обратите внимание, что вы также должны запомнить режим изображения, т. е. был ли он RGB или RGBA, или P, или PA, или L, или LA, или HSV и т. д. И обратите внимание, что ваши кортежи также будут иметь длину 1, 2, 3 или 4 вместо того, чтобы всегда предполагать 3. Позже вы также поймете, что вам, возможно, придется иметь дело с 16/32/64 бит/образцами изображений, поэтому вам нужно будет помнить и об этом, в дополнение к вышесказанному.

Ответ принят как подходящий

Марк Сетчелл был ПОЧТИ прав. Его код помог мне получить изображение, но за одно оно повторилось 4 раза.

В строке кода Марка было переключение (с высотой h и шириной w):

array = np.array(PixelArray, dtype=np.uint8).reshape(h,w,3)

Это моя строка кода:

array = np.array(PixelArray, dtype=np.uint8).reshape(w, h, 3)

Это не правильно. Для массивов Numpy на первом месте стоит высота. Попробуйте это w, h = 640, 480, затем сначала создайте массив Numpy с высотой na = np.zeros((h,w,3), np.uint8), затем создайте PIL Image и отобразите его Image.fromarray(na).show(), и вы увидите, что изображение PIL шире, чем высота, и соответствует форме (h,w,3).

Mark Setchell 24.08.2024 17:14

Другие вопросы по теме