Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stack multiple images in python pillow

I am trying to do some image stacking in python pillow. What I would like to do is take a large number of images (say 10), and then for each pixel, take the median value like this: http://petapixel.com/2013/05/29/a-look-at-reducing-noise-in-photographs-using-median-blending/.

Right now, I can do it in an incredibly brute force manner (using getpixel and put pixel), but it takes a very long time.

Here is what I have so far:

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()
like image 866
user1763510 Avatar asked Jan 06 '16 01:01

user1763510


People also ask

How do I combine multiple images in Python?

The merge() function accepts a mode and a tuple of images as parameters, and combines them into a single image.

How do you load and manipulate images with PIL Pillow?

PIL image to NumPy array After converting an image to NumPy array we can read it in using PIL. With the image converted we can now load it using Pillow. This is done using the fromarray function of Pillow's Image class. Finally, we save and display the image using PIL show image function.

How do you insert an image into a Pillow in Python?

To load the image, we simply import the image module from the pillow and call the Image. open(), passing the image filename. Instead of calling the Pillow module, we will call the PIL module as to make it backward compatible with an older module called Python Imaging Library (PIL).


1 Answers

You can vectorise a lot of these loops with arrays. For example np.array(im) will return an array of the pixels, with a shape (400, 300, 3). So to store everything in an array.

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)

Now you can calculate the median with your preferred way, but numpy has a method for that, too.

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

Two things to notice here is that np.median() will return a float type array, and we want to convert that to unsigned int8. The other thing is that if the number of elements is even, the median is calculated as the mean of the two middle values, which may end up being an odd number divided by two, such as 13.5. But when this is converted to integer, it will be rounded down. Such minor precision loss should not visually affect your result.

like image 121
Reti43 Avatar answered Oct 01 '22 22:10

Reti43