Tutorial: Smooth 3D printing timelapse by optimal frame selection

To process video files OpenCV has to be compiled with ffmpeg option. On Windows it was a bit of a fight until I found out about Anaconda: https://www.anaconda.com/download/

In the Anaconda prompt you can just execute

conda install -c menpo opencv3 ffmpeg

and satisfy the other requirements normally.

#!/usr/bin/env python
 
import numpy as np
import cv2
from skimage.measure import compare_ssim as ssim
import time
 
cap = cv2.VideoCapture('video.mp4')
 
ret,previous = cap.read()
best_frame = previous
number = 50
file = 0
 
while(True):
    i = 0
    best_s = 0
    while(i<=number):
    i += 1
    ret, frame = cap.read()
    s = ssim(frame, previous, multichannel=True)
    if(s > best_s):
        best_s = s
        best_frame = frame
    cv2.imwrite('folder/%d.png' % file,best_frame)
    file += 1
    previous = best_frame
 
cap.release()
cv2.destroyAllWindows()

A few ideas to improve performance in the future:

Simplify images before comparing them

This needs a run-time analysis to make sure that the simplifications actually improve speed. The idea is that it would be sufficient to look at a single channel image with half the size instead of RGB Full HD to measure similarity.

Make decisions more dynamic

When similarity is larger than a certain threshold and the frame is far enough away from the last, we can use that one right away instead of going through all the remaining candidates.

Implement the whole thing in C++

The actual comparison that is taking a lot of time is done in python scikit-image. Python is a relatively abstract language that’s made for people who want to solve algorithmic problems instead of worrying about syntax. That’s why there are no type declarations, no pointer arithmetic, etc. but on the other hand is a bit slower!

Use multithreading

You could start one thread for every comparison and distribute them to CPU cores or even GPU! I am seeing about 15% CPU utilization when the script is running.

Leave a Reply