简体   繁体   English

NumPy,PIL添加图像

[英]NumPy, PIL adding an image

I'm trying to add two images together using NumPy and PIL. 我正在尝试使用NumPy和PIL将两个图像组合在一起。 The way I would do this in MATLAB would be something like: 我在MATLAB中这样做的方式如下:

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

I get something like this: 我得到这样的东西:

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

Using a compositing program and adding the images the MATLAB result seems to be right. 使用合成程序并添加图像,MATLAB结果似乎是正确的。

In Python I'm trying to do the same thing like this: 在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')

and I get something like this: 我得到这样的东西:

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

Why am I getting all those funky colors? 为什么我会得到所有那些时髦的颜色? I also tried using ImageMath.eval("a+b", a=im1, b=im2) , but I get an error about RGB unsupported. 我也尝试使用ImageMath.eval("a+b", a=im1, b=im2) ,但是我得到一个关于RGB不支持的错误。

I also saw that there is an Image.blend() but that requires an alpha. 我还看到有一个Image.blend()但需要alpha。

What's the best way to achieve what I'm looking for? 什么是实现我正在寻找的最佳方式?

Source Images (images have been removed): 源图像(图像已被删除):

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

Humm, OK, well I added the source images using the add image icon and they show up when I'm editing the post, but for some reason the images don't show up in the post. 嗯,好吧,我使用添加图片图标添加了源图像,当我正在编辑帖子时它们出现,但由于某种原因,图像没有显示在帖子中。

(images have been removed) 2013 05 09 (图片已被删除)2013 05 09

As everyone suggested already, the weird colors you're observing are overflow. 正如大家所说的那样,你所观察到的怪异颜色是溢出的。 And as you point out in the comment of schnaader's answer you still get overflow if you add your images like this: 正如你在schnaader的回答评论中指出的那样,如果你添加这样的图像,你仍然会溢出

addition=(im1arr+im2arr)/2

The reason for this overflow is that your NumPy arrays ( im1arr im2arr ) are of the uint8 type (ie 8-bit). 这种溢出的原因是你的NumPy数组( im1arr im2arr )属于uint8类型(即8位)。 This means each element of the array can only hold values up to 255, so when your sum exceeds 255, it loops back around 0: 这意味着数组的每个元素只能保存最多255个值,所以当你的总和超过255时,它会回到0:

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

To avoid overflow, your arrays should be able to contain values beyond 255. You need to convert them to floats for instance, perform the blending operation and convert the result back to uint8 : 为避免溢出,您的数组应该能够包含超过255的值。例如,您需要将它们转换为浮点数 ,执行混合操作并将结果转换回uint8

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

You should not do this: 不应该这样做:

addition = im1arr/2 + im2arr/2

as you lose information, by squashing the dynamic of the image (you effectively make the images 7-bit) before you perform the blending information. 当您丢失信息时,通过在执行混合信息之前压缩图像的动态(有效地使图像为7位)。

MATLAB note : the reason you don't see this problem in MATLAB, is probably because MATLAB takes care of the overflow implicitly in one of its functions. MATLAB注意 :你在MATLAB中没有看到这个问题的原因可能是因为MATLAB在其中一个函数中隐含地处理溢出。

Using PIL's blend() with an alpha value of 0.5 would be equivalent to (im1arr + im2arr)/2. 使用PIL的blend(),其alpha值为0.5,相当于(im1arr + im2arr)/ 2。 Blend does not require that the images have alpha layers. Blend不要求图像具有alpha图层。

Try this: 尝试这个:

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

It seems the code you posted just sums up the values and values bigger than 256 are overflowing. 您发布的代码似乎只是总结了值,大于256的值溢出。 You want something like "(a + b) / 2" or "min(a + b, 256)". 你想要“(a + b)/ 2”或“min(a + b,256)”之类的东西。 The latter seems to be the way that your Matlab example does it. 后者似乎是你的Matlab示例的方式。

To clamp numpy array values: 要钳制numpy数组值:

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

Your sample images are not showing up form me so I am going to do a bit of guessing. 你的样本图像没有出现在我身上,所以我要做一些猜测。

I can't remember exactly how the numpy to pil conversion works but there are two likely cases. 我不记得numpy到pil转换是如何工作的,但有两种可能的情况。 I am 95% sure it is 1 but am giving 2 just in case I am wrong. 我95%肯定它是1但是我给2以防万一我错了。 1) 1 im1Arr is a MxN array of integers (ARGB) and when you add im1arr and im2arr together you are overflowing from one channel into the next if the components b1+b2>255. 1)1 im1Arr是一个MxN整数数组(ARGB),当你将im1arr和im2arr加在一起时,如果组件b1 + b2> 255,则会从一个通道溢出到下一个通道。 I am guessing matlab represents their images as MxNx3 arrays so each color channel is separate. 我猜测matlab将它们的图像表示为MxNx3阵列,因此每个颜色通道都是独立的。 You can solve this by splitting the PIL image channels and then making numpy arrays 您可以通过拆分PIL图像通道然后制作numpy数组来解决此问题

2) 1 im1Arr is a MxNx3 array of bytes and when you add im1arr and im2arr together you are wrapping the component around. 2)1 im1Arr是一个MxNx3字节数组,当你将im1arr和im2arr一起添加时,你将组件包裹起来。

You are also going to have to rescale the range back to between 0-255 before displaying. 在显示之前,您还必须将范围重新缩放到0-255之间。 Your choices are divide by 2, scale by 255/array.max() or do a clip. 您的选择除以2,缩放255 / array.max()或做一个剪辑。 I don't know what matlab does 我不知道matlab是做什么的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM