, , , , , , , , , , , , ,

Arkwood shat his pants. He was at the cinema, on a hot date with Daphne, when his undergarments were breached.

‘It was terrible!’ Arkwood cried, ‘The movie was so scary, I could not contain myself.’

I told him not to worry. ‘Maybe if you direct your very own scary movie, you will conquer your fears?’

Arkwood thought it a great idea, and started in earnest to create a horror flick using PyMovieStudio, a free Python application for making movies.

Recording the movie

PyMovieStudio lets you plug up to 4 webcams into a single PC, and shoot a movie from multiple camera angles simultaneously! Arkwood chose to record his scary movie with 3 webcams (2 webcams plugged into the front USB panel of his PC, 1 webcam plugged into the back).

Editing the movie

Next up, Arkwood used the power of his voice to edit the movie. He shouted the camera angles into his computer microphone – “Two”, “One”, he boomed – and PyMovieStudio used Google Speech Recognition to cut between his recorded camera angles.

Adding special effects to the movie

It’s all very well recording and editing a movie, but how do you make it scary? What about some special effects!

Arkwood added an OpenGL graphics library fog effect to the movie. That’s eerie.

Then – being a superstitious fellow – he added some OpenCV computer vision to track the colour green. If any green should appear in the movie he will train crosshairs on it and fire a gun. Death to all that emits green. And it would be remiss not to have a bit of flashing OpenGL lighting during those rounds of artillery.

Adding audio to the movie

So far, so good, so what, as Megadeth would say. What we need to cap it off is a slice of spine-chilling audio. Freesound provided the spooky soundtrack and harrowing scream to Arkwood’s cinematic masterpiece.

Screening the movie

As you can see, PyMovieStudio lets you easily put together a gory picture. Now it is time to sit back in our cramped popcorn-strewn fuzzy red chair and watch the flick.

Here’s a still from camera one:


And camera three:


And finally, the all too much monstrous camera two:


And if you want to watch the whole scary movie, here it is:

What great work! The vocal chords editing three camera angles into one. Fog, and flashing lights, and crosshairs tracking the colour green (even the reflected colour green, did you spy?). Topped off with a some petrifying sounds.

‘Now that you have directed your own scary movie,’ I said to Arkwood, ‘you will not shit yourself at the cinema. Maybe the next girl will be for keeps?’

Arkwood looked at me, bemused. ‘What do you mean? Daphne did not leave me after I shat myself. Far from it. She said she liked the smell.’

I told him that he should pursue a new dame. ‘For God’s sake man, dump her. She’s a nutter!’

‘You don’t understand,’ he replied dismissively, ‘And if you will excuse me, I need to visit the toilet. I promised Daphne a fresh present.’

Oh dear.



You can learn more about making movies with Python at the PyMovieStudio Wiki.

Here’s the Python fog method, which initialises OpenGL fog and then varies its fog_start value to create a creepy mist effect:

# apply fog
def fog(self, fog_start):

    if not self.is_fog_init:
        glFogi(GL_FOG_MODE, GL_LINEAR)
        glFogfv(GL_FOG_COLOR, (0.5, 0.5, 0.5, 1.0))
        glHint(GL_FOG_HINT, GL_NICEST)
        glFogf(GL_FOG_END, 12.0)
        self.is_fog_init = True            

    glFogf(GL_FOG_START, fog_start)

Here’s the Python lighting method, which initialises OpenGL lighting and then switches it on and off to create a shocking flash effect:

# apply lighting
def lighting(self, is_enabled):

    if not self.is_lighting_init:
        glLightfv(GL_LIGHT0, GL_AMBIENT, (0.5, 0.5, 0.5, 1.0))
        glLightfv(GL_LIGHT0, GL_DIFFUSE, (1.0, 1.0, 1.0, 1.0))
        glLightfv(GL_LIGHT0, GL_POSITION, (0.0, 0.0, 2.0, 1.0))
        self.is_lighting_init = True

    if is_enabled:

And finally a snippet of the OpenCV colour tracking code, which inspects each frame of the movie for the colour green:

# convert frame from BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

# only get colours in range
mask = cv2.inRange(hsv, self.COLOUR_LOWER, self.COLOUR_UPPER)

We can define our green colour range as thus:

COLOUR_LOWER = (58,50,50)
COLOUR_UPPER = (78,255,255)