MotionCamera

From Osvidwiki
Jump to: navigation, search

Based on motion, the GNU/Linux software motion detector.

See a result: http://player.vimeo.com/video/14884038?title=0&byline=0&portrait=0

Capturing images[edit]

motion.conf[edit]

The motion.conf settings are important.

# output_normal: Values: on, off, first, best / Default: on
# output_normal on

videodevice /dev/video0

width 640
height 480

# save images in "source"
target_dir source

# call the python script for every image
on_picture_save ./crop %f %K %L %i %J

# draw box indicating motion area
locate off

gap 0

noise_level 255

# switchfilter true

# threshold is # pixels so for 640x480, max = 307200
threshold 1

# default filenames (timestamp) + position & size
jpeg_filename %v-%Y%m%d%H%M%S-%q_%Kx%Lx%ix%J

###  %K = x, %L = y, %i = width, %J = height, %f = the filename

crop[edit]

This script, called by motion on every frame, actually performs a crop on the image.

crop

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys, os, Image

fname = sys.argv[1]
(x, y, w, h) = [int(x) for x in sys.argv[2:]]

# print fname, x, y, w, h

# x,y is CENTER of motion box, correct
x -= (w/2)
y -= (h/2)

base = os.path.splitext(os.path.split(fname)[1])[0]
im = Image.open(fname)
crop = im.crop((x, y, x+w, y+h))
out = Image.new("RGBA", (w, h), (0,0,0))
out.paste(crop, (0, 0))            
out.save("out/%s.jpg" % base)

motioncam[edit]

motioncam is a pygame application that allows a joystick (or keyboard/mouse) to start / stop image capture. Using motioncam allows the software to be carried around in a bag and started/stopped with the push of a joystick. Sound effects indicate whether the camer is starting or stopping recording. Makes use of PygHandler.py and shell.py. NB: Requires two sounds files (here called tone_up.wav, tone_down.wav), and it calls "aplay" (from alsa) to play the sounds.

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import os, sys, pygame, datetime
from shell import shell

# motion command
motion = shell("motion -cmotion.conf")

def record ():
    if not motion.is_running():
        print "start"
        os.system("aplay tone_up.wav")
        if not os.path.exists("source"):
            os.mkdir("source")
        if not os.path.exists("out"):
            os.mkdir("out")
        motion.start()
    else:
        print "stop"
        os.system("aplay tone_down.wav")
        motion.stop()
        try:
            if os.listdir("out"):
                name = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
                os.rename("out", name)
                os.system("rm source/*")
        except OSError:
            pass

pygame.init()
pygame.joystick.init()
if pygame.joystick.get_count() > 0:
    print "found joystick"
    stick = pygame.joystick.Joystick(0)
    stick.init()

size = width, height = 640, 480
black = 0, 0, 0
screen = pygame.display.set_mode(size)
running = True

from PygHandler import PygHandler
handler = PygHandler()

handler.register('record', record)

if os.path.isfile("motioncam.controls"):
    handler.load_training("motioncam.controls")
else:
    if handler.train():
        handler.save_training("motioncam.controls")

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
            running = False
        handler.handle(event)

    screen.fill(black)
    pygame.display.flip()

Constructing a movie from the captured images[edit]

So once you've recorded images using motioncam, makemovie creates sequential frames of a final movie. The last step is to use the frames2movie command to join the frames in a single video file.

makemovie[edit]

Turns folders of images into movies.

#!/usr/bin/env python
#-*- coding:utf-8 -*-
import sys, Image

"""
usage:
./makemovie ~/motioncam/2010* 

creates
/tmp

"""

import os, re
from datetime import datetime
# datepat = re.compile(r"(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)")
WEEKDAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"]

filenamepat = re.compile(r"(?:\d+)\-(?P<year>\d\d\d\d)(?P<month>\d\d)(?P<day>\d\d)(?P<hour>\d\d)(?P<min>\d\d)(?P<sec>\d\d)\-(?:\d+)_(?P<x>\d+)x(?P<y>\d+)x(?P<width>\d+)x(?P<height>\d+)")

def processImage (fp_src, fp_out):
    (pathname, filename) = os.path.split(fp_src)
    # sample filename 01-20100926143806-02_372x131x212x262.jpg
    m = filenamepat.search(filename)
    if not m:
        print "bad filename", fp_src
        return

    d = m.groupdict()
    for name, value in d.items():
        d[name] = int(value)
    # print vals

    d['x'] -= (d['width'] / 2)
    d['y'] -= (d['height'] / 2)

    im = Image.open(fp_src)
    # trim the image a little (to avoid the frame lines from motion?)???
    # crop = im.crop((x, y, x+w, y+h))
    outputimage.paste(im, (d['x'], d['y']))            
    outputimage.save("tmp.jpg")
    
    # ADD DATE CAPTION
    date = datetime(d['year'], d['month'], d['day'], d['hour'], d['min'], d['sec'])
    weekday = WEEKDAYS[date.weekday()]
    caption = WEEKDAYS[date.weekday()]+(" %02d "%d['day'])+MONTHS[d['month']-1]+" "+str(d['year'])+(" %02d:%02d"%(d['hour'],d['min']))

    # print caption
    convert_src = "tmp.jpg"
    cmd = """convert -background '#0008' -fill white -gravity SouthWest -size 640x36 \
            -font /home/murtaugh/.fonts/NotCourierSansBold.otf -pointsize 36 \
            caption:"%s" \
            +size "%s" +swap -gravity south -composite "%s" """ % (caption, convert_src, fp_out)
    # print cmd 
    os.system(cmd)

    # RENAME / MOVE TO FINAL NICELY NAMED FILE
    # newname = "%04d%02d%02d_%02d%02d%02d.jpg" % (year, month, day, h, m, s)
    # cmd = "mv temp2.jpg \"out/%s\"" % newname
    # os.system(cmd)

import sys, os
import Image, ImageDraw

outputimage = Image.new("RGBA", (640, 480), (0,0,0))
draw = ImageDraw.Draw(outputimage)

if not os.path.isdir("tmp"):
    os.mkdir("tmp")
  
folders = []
for name in sys.argv[1:]:
    folders.append(name)

folders.sort()
for folder in folders:
    name = folder.rstrip("/")
    os.system("rm tmp/*")
    c = 0
    print folder
    files = os.listdir(folder)
    files.sort()
    for filename in files:
        if filename.endswith(".jpg"):
            fp = os.path.join(folder, filename)
            c+=1
            out = os.path.join("tmp", "frame%06d.jpg" % c)
            try:
                processImage(fp, out)
            except IOError:
                pass
            #
            # draw.rectangle(outputimage.getbbox(), fill=(0,0,0))
    # blank image
    # draw.rectangle(outputimage.getbbox(), fill=(0,0,0))
    os.system("""mencoder "mf://tmp/*.jpg" -mf fps=25 -o "%s.avi" -ovc lavc -lavcopts vcodec=mjpeg:vbitrate=6400""" % name)
    os.system("rm tmp/*")