How to add parameters to fl_image in MoviePy?

Viewed 1476

From what I understand, fl_image accepts a pipeline function that should only accept a single image, i.e. processedClip = input_file.fl_image(imagePipeline)

where

def imagePipeline(img):

....

return finalImage

But what if our imagePipeline function takes in more arguments

i.e.

def imagePipeline(img, arg1, arg2, arg3):

...

return finalImage

How can we add arguments to our imagePipeline in fl_image?

4 Answers

You can use the lambda trick:

from moviepy.editor import VideoFileClip

def change_image(image, param):
    return image + param

myparam = 1
modified_clip = (
   VideoFileClip('/path/to/my/initial/clip')
   .fl_image(lambda image: change_image(image, myparam))
)

I had the same trouble and solved it with class.

class ProcessImage:
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2
    def __call__(self, image):
        # any process you want
        return image

clip = VideoFileClip('input.mp4')
final_clip = clip.fl_image(ProcessImage(1, 2))
final_clip.write_videofile('output.mp4')

You could use a closure (less boilerplate than a class):

def mkproc(*args,*kw):
    def fun(img):
        #this code has access to args and kw
        return img
    return fun

final = clip.fl_image(mkproc("foo","bar",spam="eggs"))

functools.partial does this too. For example:

import functools
import cv2

blur5 = functools.partial(cv2.GaussianBlur,ksize=(5,5),sigmaX=0)
Related