在 python 个枕头中堆叠多张图片

Stack multiple images in python pillow

我正在尝试在 python 枕头中进行一些图像堆叠。我想做的是拍摄大量图像(比如 10 张),然后对每个像素取中值,如下所示:http://petapixel.com/2013/05/29/a-look-at-reducing-noise-in-photographs-using-median-blending/.

现在,我可以用一种令人难以置信的蛮力方式(使用 getpixel 和 put pixel)来完成它,但这需要很长时间。

这是我目前的情况:

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

您可以用数组向量化很多这样的循环。例如 np.array(im) 将 return 一个像素数组,形状为 (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 也有一个 method

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

这里需要注意的两件事是 np.median() 将 return 一个 float 类型数组,我们想将其转换为 unsigned int8。另外一个就是如果元素个数是偶数,中位数是计算中间两个值的平均值,结果可能是奇数除以2,比如13.5。但是当它被转换为整数时,它会被向下舍入。这种微小的精度损失不应在视觉上影响您的结果。