For example, I have 100 pictures whose resolution is the same, and I want to merge them into one picture. For the final picture, the RGB value of each pixel is the average of the 100 pictures’ at that position. I know the getdata
function can work in this situation, but is there a simpler and faster way to do this in PIL(Python Image Library)?
Advertisement
Answer
Let’s assume that your images are all .png files and they are all stored in the current working directory. The python code below will do what you want. As Ignacio suggests, using numpy along with PIL is the key here. You just need to be a little bit careful about switching between integer and float arrays when building your average pixel intensities.
import os, numpy, PIL from PIL import Image # Access all PNG files in directory allfiles=os.listdir(os.getcwd()) imlist=[filename for filename in allfiles if filename[-4:] in [".png",".PNG"]] # Assuming all images are the same size, get dimensions of first image w,h=Image.open(imlist[0]).size N=len(imlist) # Create a numpy array of floats to store the average (assume RGB images) arr=numpy.zeros((h,w,3),numpy.float) # Build up average pixel intensities, casting each image as an array of floats for im in imlist: imarr=numpy.array(Image.open(im),dtype=numpy.float) arr=arr+imarr/N # Round values in array and cast as 8-bit integer arr=numpy.array(numpy.round(arr),dtype=numpy.uint8) # Generate, save and preview final image out=Image.fromarray(arr,mode="RGB") out.save("Average.png") out.show()
The image below was generated from a sequence of HD video frames using the code above.