{1471} revision 3 modified: 07-30-2019 20:45 gmt

Edited Terrence Eden's script to average multiple frames when producing a time-lapse video from a continuous video. Frames are averaged together before decimation, rather than pure decimation, as with ffmpeg. Produces appealing results on subjects like water. Also, outputs a video directly, without having to write individual images.

python
#!/usr/bin/python
import cv2
import sys

#   Video to read
print str(sys.argv[1])
vidcap = cv2.VideoCapture(sys.argv[1])

#   Which frame to start from, how many frames to go through
start_frame = 0
frames = 61000

#   Counters
count = 0
save_seq = 0
decimate = 10
rolling = 16 # average over N output frames
transpose = False

if(transpose):
	h = vidcap.get(3)
	w = vidcap.get(4)
else:
	w = vidcap.get(3)
	h = vidcap.get(4)

fourcc = cv2.VideoWriter_fourcc(*'mp4v')
writer = cv2.VideoWriter("timelapse.mp4", fourcc, 30, (int(w), int(h)), True)

avglist = []

while True:
	#   Read a frame
	success,image = vidcap.read()
	if not success:
		break
	if count > start_frame+frames:
		break
	if count >= start_frame:
		if (count % decimate == 0):
			#   Extract the frame and convert to float
			avg = image.astype('uint16') # max 255 frames averaged. 
		if (count % decimate > 0 and count % decimate <= (decimate-1)):
			avg = avg + image.astype('uint16')
		if (count % decimate == (decimate-1)):
			#   Every 100 frames (3 seconds @ 30fps)
			avg = avg / decimate
			if(transpose):
				avg = cv2.transpose(avg)
				avg = cv2.flip(avg, 1)
			avg2 = avg; 
			for a in avglist:
				avg2 = avg2 + a
			avg2 = avg2 / rolling; 
			avglist.append(avg); 
			if len(avglist) >= rolling:
				avglist.pop(0) # remove the first item. 
			
			avg2 = avg2.astype('uint8')
			print("saving "+str(save_seq))
			#   Save Image
			# cv2.imwrite(filename+str('{0:03d}'.format(save_seq))+".png", avg)
			save_seq += 1
			writer.write(avg2)
			if count == frames + start_frame:
				break
	count += 1
writer.release()