Статическое изображение, отображаемое при сохранении изображений PIL в массив 4D Numpy

1

У меня есть следующий код Python, где я храню некоторые изображения формы 326x490x3 как numpy массивы для предварительной обработки на более позднем этапе. Я хочу сохранить мои изображения в массиве 4D NumPy, чтобы позже я смог обработать их партиями. Код работает нормально, но я обнаружил, что когда я конвертирую каждый 3D-элемент массива 4D обратно в RGB-изображение, я просто получаю статическое изображение.

КОД:

data = np.zeros((129, 326, 490, 3))
image_path = '0.jpg'
img = Image.open(image_path)
data[0,:,:,:] = np.asarray(img)
im = Image.fromarray(data[0], 'RGB')
im.show()

ВЫХОД:

Изображение 174551

Но когда я пытаюсь отобразить срез трехмерного массива из массива 4D в виде изображения в градациях серого, он работает нормально.

КОД:

data = np.zeros((129, 326, 490, 3))
image_path = '0.jpg'
img = Image.open(image_path)
data[0,:,:,:] = np.asarray(img)
im = Image.fromarray(np.dot(data[0], [0.299, 0.587, 0.114]))
im.show()

ВЫХОД:

Изображение 174551

Приведенное здесь решение работает, как и ожидалось, когда я сохраняю изображение в виде трехмерного массива и переключаюсь обратно в изображение PIL.

КОД:

data = np.zeros((129, 326, 490, 3))
image_path = '0.jpg'
img = Image.open(image_path)
im = Image.fromarray(np.asarray(img), 'RGB')
im.show()

ВЫХОД:

Изображение 174551

Может кто-нибудь объяснить, пожалуйста, это поведение? Я не понимаю, как код работает, как ожидается, для трехмерного массива массивов, но работает по-разному для среза трехмерного массива массива 4D.

Теги:
image-processing
numpy
python-imaging-library

1 ответ

2
Лучший ответ

Тип данных по умолчанию для массива, созданного с помощью numpy.zeros - это numpy.float64 (т.е. с плавающей запятой). Таким образом, data являются массивом с плавающей запятой. В строке im = Image.fromarray(data[0], 'RGB'), вы явно указан режим, чтобы быть 'RGB', что означает 8 - битные целые числа (см Modes документацию), так fromarray интерпретирует аргумент data[0] как массив 8-битных целых чисел. По-видимому, он не пытается преобразовать входной массив; это просто предполагает, что базовые данные в массиве хранятся как 8-битные целые числа. Поскольку data[0] самом деле содержит значения с плавающей запятой, результат неверен.

В случае, когда вы используете im = Image.fromarray(np.dot(data[0], [0.299, 0.587, 0.114])), вы явно не указали режим, поэтому fromarray использует свой собственный код для определения режима, который в этом случае будет 'F' (32-битная с плавающей запятой). Так что он правильно конвертирует ваши данные. Например, если вы указали режим 'L' (что означает 8-битный черно-белый) (т.е. im = Image.fromarray(np.dot(data[0], [0.299, 0.587, 0.114]), 'L')), вызов будет успешным, но данные изображения снова будут неверными, потому что fromarray будет интерпретировать память, которая содержит значения с плавающей запятой, как если бы она содержала 8-битные целочисленные пиксели.

Вероятно, самое простое решение - создать data в виде массива 8-битных целых чисел без знака:

data = np.zeros((129, 326, 490, 3), dtype=np.uint8)
  • 0
    Спасибо, Уоррен!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню