MotionCamera
Based on motion, the GNU/Linux software motion detector.
See a result: http://player.vimeo.com/video/14884038?title=0&byline=0&portrait=0
Contents
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/*")