Skip to content

Instantly share code, notes, and snippets.

@stuarta0
Created August 28, 2022 23:02
Show Gist options
  • Select an option

  • Save stuarta0/188ce1648787d86dbec64418c68d89ce to your computer and use it in GitHub Desktop.

Select an option

Save stuarta0/188ce1648787d86dbec64418c68d89ce to your computer and use it in GitHub Desktop.
Frame blending motion blur
#!/usr/bin/python
import os
import re
from PIL import Image
# settings
input_folder = 'input-sequence'
input_filename_pattern = 'movie(\d+).png'
output_folder = 'output-blend'
output_filename_pattern = 'movie {:04}.png'
source_fps = 240
target_fps = 24
shutter_angle = 180
overwrite = False
# process
step = int(source_fps / target_fps)
combine = int((shutter_angle / 360) * step)
if step <= 0 or combine <= 0 or combine > step:
exit
frames = [m.group(0) for m in sorted(filter(None, [re.match(input_filename_pattern, f) for f in os.listdir(input_folder)]), key=lambda m: int(m.group(1)))]
for i, c in enumerate(range(0, len(frames), step)):
print(f'Processing output frame {i}')
target = os.path.join(output_folder, output_filename_pattern.format(i))
if not overwrite and os.path.exists(target):
continue
chunk = frames[c:c+step]
frame = None
if combine > len(chunk):
continue
# combine = number of frames to combine in this chunk based on shutter angle
for j in range(combine):
filename = os.path.join(input_folder, chunk[j])
if frame:
cur = Image.open(filename)
# 0=100%, 1=50%, 2=33%, 3=25%, 4=20%
frame = Image.blend(frame, cur, 1 / (j + 1))
else:
frame = Image.open(filename)
frame.save(target)
@VikSarMS
Copy link

Well done

@stuarta0
Copy link
Author

After the documentation was updated for the Godot 4.0 release in 2023, it showed a one-liner using ffmpeg instead!

https://docs.godotengine.org/en/stable/tutorials/animation/creating_movies.html#generating-accumulation-motion-blur-with-ffmpeg

Example with a 240 FPS source video, generating 4× motion blur and decreasing its output framerate to 60 FPS:

ffmpeg -i input.avi -vf "tmix=frames=4, fps=60" -crf 15 output.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment