Skip to content

Instantly share code, notes, and snippets.

@Jip-Hop
Created January 8, 2016 15:56
Show Gist options
  • Save Jip-Hop/112ef3a24eaa4d87767a to your computer and use it in GitHub Desktop.
Save Jip-Hop/112ef3a24eaa4d87767a to your computer and use it in GitHub Desktop.
# references used:
# http://stackoverflow.com/questions/17291455/how-to-get-an-average-picture-from-100-pictures-using-pil
# http://stackoverflow.com/questions/16135677/efficient-way-to-find-median-value-of-a-number-of-rgb-images
import os, numpy, PIL
from PIL import Image
start_frame = 0 # the frame number starts at 0
jpgs_in_dir = {}
max_frames_in_dir = {}
max_frames = 0
w = 0
h = 0
output_folder = 'median_output'
def get_immediate_subdirectories(a_dir):
return [name for name in os.listdir(a_dir)
if os.path.isdir(os.path.join(a_dir, name)) and name != output_folder]
def path_to_sub_dir(sub_dir):
return os.getcwd() + '/' + sub_dir
def path_to_jpg(sub_dir, filename):
return path_to_sub_dir(sub_dir) + '/' + filename
# average pixels
# def process_images(imlist, N, x):
# # 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(os.getcwd() + "/" + output_folder + "/" + str(x) + ".jpg")
# #out.show()
# median pixels
def process_images(imlist, N, x):
# read the images into a stack
stack = []
for im in imlist:
stack.append(numpy.array(Image.open(im),dtype=numpy.uint8))
# flatten the images in the stack (so RGB values are no longer in a multidimensional list)
Y = numpy.vstack((im.ravel() for im in stack))
# calculate the median
median = numpy.median(Y,axis = 0)
# reshape back to the correct dimensions and depth (RGB)
median = numpy.uint8(median.reshape(h,w,3))
# Generate, save and preview final image
out=Image.fromarray(median,mode="RGB")
out.save(os.getcwd() + "/" + output_folder + "/" + str(x) + ".png")
#out.show()
sub_dirs = get_immediate_subdirectories(os.getcwd())
if not os.path.exists(os.getcwd() + "/" + output_folder):
os.makedirs(os.getcwd() + "/" + output_folder)
for dir in sub_dirs:
# Access all files in the chosen sub-directory
allfiles = os.listdir(path_to_sub_dir(dir))
# filter out only JPG files
imlist = [filename for filename in allfiles if filename[-4:] in [".jpg",".JPG"]]
# if the width and height haven't been defined yet and there is an image in the dir, define w and h
if ((not w or not h) and len(imlist) > 0):
# Assuming all images are the same size, get dimensions of first image
w,h=Image.open(path_to_jpg(dir, imlist[0])).size
# store all JPG filenames in the dictionary
jpgs_in_dir[dir] = imlist
max_frames_in_dir[dir] = len(imlist)
print "max frames in dir " + str(dir) + ": " + str(max_frames_in_dir[dir])
# extract the max number of frames, so we know when to stop processing
max_frames = max(max_frames_in_dir.values())
print max_frames
print w,h
# process all frames
for x in range(start_frame, max_frames):
print x
# the number of frames to average at this time step
N = len(sub_dirs)
imlist = []
y = 0
while (y < N):
dir = sub_dirs[y]
# we have processed all the frames in this directory
if ((max_frames_in_dir[dir]-1) < x):
# don't process this directory again, remove it
print "pop " + dir
print sub_dirs.pop(y)
# the number of frames to average has decreased
N = N-1
# don't increase y, because of .pop() we will already address
# the next element in the next iteration
else:
# add the filename of the dir to process
imlist.append(path_to_jpg(dir, jpgs_in_dir[dir][x]))
y += 1
process_images(imlist, N, x)
print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment