Подтвердить что ты не робот

NumPy, PIL, добавляющий изображение

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

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

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

alt text 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')

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

alt text http://www.deadlink.cc/python.jpg

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

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

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

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

alt text http://www.deadlink.cc/_1.jpg alt text http://www.deadlink.cc/_2.jpg

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

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

4b9b3361

Ответ 1

Как и все предлагали, странные цвета, которые вы наблюдаете, переполнены. И как вы указываете в комментарии ответа 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. Вам нужно преобразовать их в float, выполнить операцию смешивания и преобразовать результат обратно в 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 неявно заботится о переполнении одной из своих функций.

Ответ 2

Использование PIL blend() с альфа-значением 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')

Ответ 3

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

Ответ 4

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

>>> c = a + b
>>> c[c > 256] = 256

Ответ 5

Образцы с образцами не отображаются, так что я собираюсь немного угадать.

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

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

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