在Python Pillow中堆叠多个图像

5
我正在尝试使用Python Pillow进行图像叠加。 我想做的是获取大量图片(比如10张),然后对于每个像素,取中间值,就像这样:http://petapixel.com/2013/05/29/a-look-at-reducing-noise-in-photographs-using-median-blending/
目前,我可以用一种非常原始的方式(使用getpixel和putpixel)来实现它,但需要花费很长时间。
以下是我迄今为止所拥有的:
import os
from PIL import Image
files = os.listdir("./")
new_im = Image.new('RGB', (4000,3000))
ims={}
for i in range(10,100):
    ims[i]={}           
    im=Image.open("./"+files[i])
    for x in range(400):
        ims[i][x]={}            
        for y in range(300):
            ims[i][x][y]=im.getpixel((x,y))

for x in range(400):
    for y in range(300):
        these1=[]
        these2=[]
        these3=[]
        for i in ims:
            these1.append(ims[i][x][y][0])
            these2.append(ims[i][x][y][1])
            these3.append(ims[i][x][y][2])
        these1.sort()
        these2.sort()
        these3.sort()
        new_im.putpixel((x,y),(these1[len(these1)/2],these2[len(these2)/2],these3[len(these3)/2]))

new_im.show()
1个回答

6

您可以使用数组来向量化许多这些循环。例如,np.array(im)将返回一个像素数组,其形状为(400、300、3)。因此,可以将所有内容存储在一个数组中。

image_stacks = np.zeros(shape=(10, 400, 300, 3), dtype=np.uint8)
for i in xrange(image_stacks.shape[0]):
    # open image file and store in variable `im`, then
    image_stacks[i] = np.array(im)

现在您可以用自己偏爱的方法计算中位数,但是numpy也有一个方法可以实现这个功能。

image_median = np.median(image_stacks, axis=0).astype(np.uint8)
image = Image.fromarray(image_median)

需要注意的两个问题是np.median()将返回一个浮点类型的数组,我们需要将其转换为无符号int8。另一件事是,如果元素数量是偶数,则中位数被计算为两个中间值的平均值,可能会得到一个被2整除的奇数,例如13.5。但是当它转换为整数时,它将被向下舍入。这样的小精度损失不应该影响您的结果。


工作速度快多了。非常感谢! - user1763510

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接