AndersM
Posts: 33
Joined: Sun Sep 06, 2015 1:18 pm

Small stop motion program for Pi Camera

Wed Jan 06, 2016 1:15 pm

As Pi Camera is small I thought it would be fun to play with stop motion animation. (The youngest son is in the LEGO-animation age...)

Having OpenCV3 installed I made a small python program for recording animations. It can handle camera up side down (it is easier to get low down that way) and overlay of last recorded frame to help place the actors. Some one else might also find it useful so here it is:

Code: Select all

from picamera.array import PiRGBArray
from picamera import PiCamera
import cv2
import time
import sys, getopt

outfile='output.avi'
framerate=25
resolution=(640,480)
blend=0.3
flip=False

#Options
try:
   opts, args = getopt.getopt(sys.argv[1:],"huo:f:r:b:")
except getopt.GetoptError:
   print('stopmotion.py -u -o <outputfile> -f <framerate> -r (<width>, <height>) -b <overlay alpha>')
   sys.exit(2)
for opt, arg in opts:
    if opt == '-h':
        print('Options:\n-u camera uppside down [False]\n-o <outputfile> [output.avi]\n-f <framerate> [25]\n-r (<width>, <height>) [640,480]\n-b <overlay alpha> [0.3]')
        print('Spacebar to capture frame. Use o to toggle last frame overlay, q to quit')
        sys.exit()
    elif opt == '-u':
        flip=True
    elif opt == '-o':
        outputfile = arg
    elif opt == '-f':
        framerate = eval(arg)
    elif opt == '-r':
        resolution = eval(arg)
    elif opt == '-b':
        blend = eval(arg)
if flip:
    print('Camera upside down')
print('Saving to '+outfile+' with framerate '+str(framerate)+' and resolution '+str(resolution))
print('Spacebar to capture frame. Use o to toggle last frame overlay, q to quit')

# initialize the camera and grab a reference to the raw camera capture
camera = PiCamera()
camera.resolution = resolution
camera.framerate = framerate
rawCapture = PiRGBArray(camera, size=resolution)

# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc('H','2','6','4')
out = cv2.VideoWriter(outfile,fourcc, framerate, resolution)

# allow the camera to warmup
time.sleep(0.1)

#Main loop
fnr=0
lastimage=None
overlay=False
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
    image = frame.array
    if flip:
        image=cv2.flip(image,-1)
    if overlay and lastimage is not None:
        cv2.imshow('Frame', cv2.addWeighted(image,1-blend,lastimage,blend,0))
    else:
        cv2.imshow('Frame',image)
    key=cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        print('Quitting and saving')
        break
    elif key == ord(' '):
        out.write(image)
        lastimage=image
        fnr=fnr+1
        print('Frame='+str(fnr))
    elif key == ord('o'):
        overlay= not overlay
        print('Overlay '+str(overlay))
    # clear the stream in preparation for the next frame
    rawCapture.truncate(0)

# Release everything
out.release()
cv2.destroyAllWindows()
Tip: Putting a small loupe in front of the camera makes it possible to take close ups

Return to “Graphics, sound and multimedia”