Numpy, Pil adicionando uma imagem
-
22-08-2019 - |
Pergunta
Estou tentando adicionar duas imagens usando Numpy e Pil. A maneira como eu faria isso em Matlab seria algo como:
>> M1 = imread('_1.jpg');
>> M2 = imread('_2.jpg');
>> resM = M1 + M2;
>> imwrite(resM, 'res.jpg');
Eu recebo algo assim:
TEXTO DE ALT HTTP://www.deadlink.cc/matlab.jpg
Usando um programa de composição e adicionando as imagens, o resultado do MATLAB parece estar certo.
Em Python, estou tentando fazer a mesma coisa assim:
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')
E eu recebo algo assim:
ALT TEXTO http://www.deadlink.cc/python.jpg
Por que estou recebendo todas essas cores descoladas? Eu também tentei usar ImageMath.eval("a+b", a=im1, b=im2)
, mas recebo um erro sobre o RGB sem suporte.
Eu também vi que existe um Image.blend()
Mas isso requer um alfa.
Qual é a melhor maneira de alcançar o que estou procurando?
Imagens de origem (imagens foram removidas):
TEXTO ALT HTTP://www.deadlink.cc/_1.jpg ALT TEXTO http://www.deadlink.cc/_2.jpg
Humm, ok, bem, adicionei as imagens de origem usando o ícone Adicionar imagem e elas aparecem quando estou editando a postagem, mas por algum motivo as imagens não aparecem na postagem.
(Imagens foram removidas) 2013 05 09
Solução
Como todos sugeriram, as cores estranhas que você está observando estão transbordando. E como você aponta no Comentário da resposta de Schnaader vocês Ainda há transbordamento Se você adicionar suas imagens como esta:
addition=(im1arr+im2arr)/2
A razão para esse transbordamento é que suas matrizes Numpy (im1arr im2arr) são do uint8 Tipo (ou seja, 8 bits). Isso significa que cada elemento da matriz só pode conter valores de até 255; portanto, quando sua soma exceder 255, ele volta em torno de 0:
>>>array([255,10,100],dtype='uint8') + array([1,10,160],dtype='uint8')
array([ 0, 20, 4], dtype=uint8)
Para evitar transbordar, suas matrizes devem poder conter valores além de 255. você precisa converte -os em carros alegóricos Por exemplo, execute a operação de mistura e Converta o resultado de volta ao UINT8:
im1arrF = im1arr.astype('float')
im2arrF = im2arr.astype('float')
additionF = (im1arrF+im2arrF)/2
addition = additionF.astype('uint8')
Você não deveria fazem isto:
addition = im1arr/2 + im2arr/2
Ao perder informações, esmagando a dinâmica da imagem (você efetivamente faz as imagens de 7 bits) antes de executar as informações de mistura.
Nota Matlab: O motivo pelo qual você não vê esse problema no Matlab é provavelmente porque o Matlab cuida do transbordamento implicitamente em uma de suas funções.
Outras dicas
Usar o Blend () PIL com um valor alfa de 0,5 seria equivalente a (IM1ARR + IM2ARR)/2. A mistura não exige que as imagens tenham camadas alfa.
Experimente isso:
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')
Parece que o código que você postou resume os valores e valores maiores que 256 estão transbordando. Você quer algo como "(a + b) / 2" ou "min (a + b, 256)". O último parece ser a maneira como seu exemplo do MATLAB faz.
Para prender valores de matriz numpy:
>>> c = a + b
>>> c[c > 256] = 256
Suas imagens de amostra não estão aparecendo me formam, então vou adivinhar um pouco.
Não me lembro exatamente como funciona a conversão Numpy para PIL, mas existem dois casos prováveis. Tenho 95% de certeza de que é 1, mas estou dando 2 para o caso de estar errado. 1) 1 IM1arr é uma matriz MXN de números inteiros (ARGB) e, quando você adiciona IM1arr e IM2arr juntos, estará transbordando de um canal para o próximo se os componentes B1+B2> 255. Acho que o Matlab representa suas imagens como matrizes mxnx3, para que cada canal de cores seja separado. Você pode resolver isso dividindo os canais de imagem PIL e depois fazendo matrizes Numpy
2) 1 IM1arr é uma matriz MxNX3 de bytes e, quando você adiciona im1arr e im2arr, está envolvendo o componente.
Você também precisará redimensionar o intervalo de volta entre 0-255 antes de exibir. Suas opções são divididas por 2, escala por 255/Array.max () ou faça um clipe. Eu não sei o que o matlab faz