NumPy, PIL добавление изображения - PullRequest
23 голосов
/ 08 февраля 2009

Я пытаюсь добавить два изображения вместе, используя NumPy и PIL. То, как я это сделал бы в MATLAB , будет примерно таким:

>> M1 = imread('_1.jpg');
>> M2 = imread('_2.jpg');
>> resM = M1 + M2;
>> imwrite(resM, 'res.jpg');

Я получаю что-то вроде этого:

альтернативный текст http://www.deadlink.cc/matlab.jpg

Используя программу компоновки и добавляя изображения, результат MATLAB представляется правильным.

В Python я пытаюсь сделать то же самое, как это:

from PIL import Image
from numpy import *

im1 = Image.open('/Users/rem7/Desktop/_1.jpg')
im2 = Image.open('/Users/rem7/Desktop/_2.jpg')

im1arr = asarray(im1)
im2arr = asarray(im2)

addition = im1arr + im2arr

resultImage = Image.fromarray(addition)
resultImage.save('/Users/rem7/Desktop/a.jpg')

и я получаю что-то вроде этого:

альтернативный текст http://www.deadlink.cc/python.jpg

Почему я получаю все эти яркие цвета? Я также попытался использовать ImageMath.eval("a+b", a=im1, b=im2), но я получаю сообщение об ошибке, что RGB не поддерживается.

Я также видел, что есть Image.blend(), но для этого требуется альфа.

Какой лучший способ добиться того, что я ищу?

Исходные изображения (изображения были удалены):

альтернативный текст http://www.deadlink.cc/_1.jpg альтернативный текст http://www.deadlink.cc/_2.jpg

Хм, хорошо, я добавил исходные изображения с помощью значка добавления изображения, и они отображаются при редактировании сообщения, но по какой-то причине изображения не отображаются в сообщении.

(изображения были удалены) 2013 05 09

Ответы [ 5 ]

29 голосов
/ 08 февраля 2009

Как уже все предлагали, странные цвета, которые вы наблюдаете, переполнены. И, как вы указали в комментарии к ответу schnaader , вы все равно получите переполнение , если добавите ваши изображения следующим образом:

addition=(im1arr+im2arr)/2

Причина этого переполнения состоит в том, что ваши массивы NumPy ( im1arr im2arr ) имеют тип uint8 (т.е. 8-битный). Это означает, что каждый элемент массива может содержать только значения до 255, поэтому, когда ваша сумма превышает 255, она возвращается к 0:

>>>array([255,10,100],dtype='uint8') +  array([1,10,160],dtype='uint8')
array([ 0, 20,  4], dtype=uint8)

Чтобы избежать переполнения, ваши массивы должны содержать значения, превышающие 255. Вам необходимо преобразовать их, например, в числа с плавающей точкой , выполнить операцию смешивания и преобразовать результат обратно в uint8 :

im1arrF = im1arr.astype('float')
im2arrF = im2arr.astype('float')
additionF = (im1arrF+im2arrF)/2
addition = additionF.astype('uint8')

Вы не должны сделать это:

addition = im1arr/2 + im2arr/2

при потере информации, сдавливая динамику изображения (вы фактически делаете изображения 7-битными), прежде чем выполнять смешивание информации.

Примечание к MATLAB : причина, по которой вы не видите эту проблему в MATLAB, возможно, в том, что MATLAB неявно заботится о переполнении в одной из своих функций.

18 голосов
/ 08 февраля 2009

Использование blend () в PIL со значением альфа 0,5 будет эквивалентно (im1arr + im2arr) / 2. Blend не требует, чтобы изображения имели альфа-слои.

Попробуйте это:

from PIL import Image
im1 = Image.open('/Users/rem7/Desktop/_1.jpg')
im2 = Image.open('/Users/rem7/Desktop/_2.jpg')
Image.blend(im1,im2,0.5).save('/Users/rem7/Desktop/a.jpg')
2 голосов
/ 08 февраля 2009

Кажется, код, который вы разместили, просто суммирует значения, а значения больше 256 переполняются. Вы хотите что-то вроде "(a + b) / 2" или "min (a + b, 256)". Последнее похоже на то, как это делает ваш пример Matlab.

1 голос
/ 08 февраля 2009

Чтобы зафиксировать значения массива:

>>> c = a + b
>>> c[c > 256] = 256
0 голосов
/ 08 февраля 2009

Ваши образцы изображений не отображаются от меня, поэтому я собираюсь немного угадать.

Я не могу точно вспомнить, как работает преобразование numpy в pil, но есть два вероятных случая. Я на 95% уверен, что это 1, но даю 2 на случай, если я ошибаюсь. 1) 1 im1Arr - массив целых чисел MxN (ARGB), и когда вы добавляете im1arr и im2arr вместе, вы переполняете один канал в другой, если компоненты b1 + b2> 255. Я предполагаю, что Matlab представляет их изображения в виде массивов MxNx3, поэтому каждый цветовой канал является отдельным. Вы можете решить эту проблему, разделив каналы изображения PIL, а затем сделав массив массивов

2) 1 im1Arr - это массив байтов MxNx3, и когда вы добавляете im1arr и im2arr вместе, вы оборачиваете компонент вокруг.

Вам также придется изменить масштаб диапазона до 0-255 перед отображением. Ваш выбор делится на 2, масштабируется на 255 / array.max () или делает клип. Я не знаю, что делает Matlab

...