2009-02-08 35 views
22

Estoy tratando de agregar dos imágenes usando NumPy y PIL. La forma en que lo haría esto en MATLAB sería algo así como:NumPy, PIL agregando una imagen

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

me sale algo como esto:

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

El uso de un programa de composición y la adición de las imágenes el resultado de MATLAB parece ser correcta .

En Python estoy tratando de hacer lo mismo de esta manera:

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

y me sale algo como esto:

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

¿Por qué recibo todos los colores de moda? También intenté usar ImageMath.eval("a+b", a=im1, b=im2), pero recibí un error sobre RGB no admitido.

También vi que hay un Image.blend() pero que requiere un alfa.

¿Cuál es la mejor manera de lograr lo que estoy buscando?

imágenes de origen (las imágenes se han eliminado):

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

Humm, OK, bueno he añadido las imágenes de origen utilizando el icono de imagen adicional y se muestran cuando estoy editando el puesto , pero por alguna razón, las imágenes no aparecen en la publicación.

(imágenes se han eliminado) 2013 05 09

Respuesta

28

Como todo el mundo ya se sugirió, los colores extraños que está observando son desbordamiento. Y como usted señala en el comment of schnaader's answer que todavía consigue desbordamiento si agrega sus imágenes como esta:

addition=(im1arr+im2arr)/2 

La razón de esto desbordamiento es que las matrices NumPy (im1arrim2arr) son del uint8 tipo (es decir, 8 bits). Esto significa que cada elemento de la matriz sólo puede contener valores de hasta 255, así que cuando su suma es superior a 255, se realiza un bucle de vuelta alrededor de 0:

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

Para evitar el desbordamiento, las matrices deben ser capaces de contener valores más allá de 255. Es necesario que convertirlos a flotadores por ejemplo, realizar la operación de mezcla y convertir el resultado a uint8:

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

usted no debería hacer esto:

addition = im1arr/2 + im2arr/2 

a medida que pierde información, al aplastar la dinámica de la imagen (efectivamente hace que las imágenes sean de 7 bits) antes de realizar la información de fusión.

MATLAB note: la razón por la que no ve este problema en MATLAB, es probablemente porque MATLAB se ocupa implícitamente del desbordamiento en una de sus funciones.

+0

Gracias, su explicación fue muy clara. – rem7

+1

¿Por qué 'flotar'? Un 'uint16' sería suficiente. – jfs

+1

No había una razón racional para elegir float, uint16 hubiera sido suficiente. – Ivan

2

Parece que el código que envió simplemente resume los valores y los valores más grandes que 256 están desbordados. Desea algo como "(a + b)/2" o "min (a + b, 256)". Esta última parece ser la forma en que lo hace tu ejemplo de Matlab.

+0

Sí, matlab fija valores al hacer aritmética en valores uint8 (por ejemplo, implícitamente hace el equivalente a max (double (a) + double (b), 256)) " –

+0

Cuando intento hacer max (im1arr + im2arr, 256) Obtengo el error: "ValueError: El valor de verdad de una matriz con más de un elemento es ambiguo. Use a.any() o a.all() " Sí (im1arr + im2arr)/2 Obtengo colores funky, solo más tenues, valor máximo 127, así que lo hice: addition = (im1arr/2) + (im2arr/2) y parece funcionar – rem7

+1

¿De verdad no quieres 'min (a + b, 256)' porque si obtienes un valor superior a 256 quieres fijar el valor en 256 (no quieres tomar un valor superior a 256). En cualquier caso, para corregir el error @ rem7 señalado, puede hacer 'additionF = np.minimal (im1arrF + im2arrF, 256)' – Vincent

0

Sus imágenes de muestra no aparecen en mi pantalla, así que voy a hacer un poco de adivinar.

No recuerdo exactamente cómo funciona la conversión de numpy a pil, pero hay dos casos probables. Estoy un 95% seguro de que es 1 pero estoy dando 2 en caso de que me equivoque. 1) 1 im1Arr es una matriz MxN de enteros (ARGB) y cuando se agregan im1arr e im2arr juntos se está desbordando de un canal al siguiente si los componentes b1 + b2> 255. Supongo que Matlab representa sus imágenes como matrices MxNx3, por lo que cada canal de color está separado. Puede resolver esto dividiendo los canales de imagen PIL y luego creando matrices numpy

2) 1 im1Arr es una matriz MxNx3 de bytes y cuando agrega im1arr e im2arr juntos está envolviendo el componente.

También tendrá que volver a escalar el rango entre 0-255 antes de mostrar. Sus elecciones se dividen por 2, escala por 255/array.max() o hace un clip. No sé lo que hace Matlab

+0

¿Las imágenes aún no se muestran? Edité la pregunta y luego eso, funciona aquí. – schnaader

+0

funciona para mí ahora. Definitivamente parece un problema de envoltura/saturación. También sería bueno si publicaras tus imágenes de origen. – hacken

+0

Creo que la conversión pil la convierte en MxNx3 ya que im1arr.shape imprime esto: (2477, 3700, 3). La opción dos parece ser correcta. – rem7

17

El uso de la combinación PIL() con un valor alfa de 0.5 sería equivalente a (im1arr + im2arr)/2. La mezcla no requiere que las imágenes tengan capas alfa.

Prueba esto:

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') 
+0

esto es especialmente bueno para hacer el trabajo sin arrastrar en numpy. – DarenW

1

para sujetar numpy valores de la matriz:

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

Supone que el tipo de elementos es más grande que uint8. – jfs

Cuestiones relacionadas