Using a DSLR
Assuming camera is supported with gphoto2:
#!/bin/bash
while (true); do
gphoto2 --capture-image-and-download &
sleep 60
done
or perhaps only --capture-image to take a photo and save to internal media (but not transfer to PC).
If you need to crop and scale images, consider using ImageMagick's mogrify:
# Crop top of image & scale to 1080p
mogrify -crop 3072x1728+0+320 -resize 1920x1080 *JPG
# Crop bottom of image (5M output from GoPro HD Hero Original) and scale to 1080p
mogrify -crop 2592x1944+0-486 -resize 1920x1080 *JPG
# Sony NEX-5n to 4K video
find . -name '*JPG' -print0 | xargs -0 -P$(nproc) -n256 gm mogrify -chop 0x501 -resize 3840x2160
If you're only capturing at 1 frame per second, you'll want to create intermediate frames so you don't need to speed up your video 60x. ImageMagick's convert's morph tool can do this:
convert -morph 28 IMG_0001.JPG IMG_0002.JPG out-%02d.jpg
If you're aiming for 30 FPS target video and want your captured photos to appear at 1 FPS, the above will create 28 intermediate frames between a pair of captured photos. Note: you probably don't want to use 1 FPS, I choose it only for example. The above will create out-01.jpg, out-02.jpg, …, out-30.jpg, where 01 and 30 were your original, captured images.
I wrote a Python script to create convert commands for me:
1 #!/usr/bin/env python
2
3 import itertools
4 import os
5
6 def iwalkByN(iterable, n):
7 iters = [itertools.islice(iterable, i, None) for i in range(n)]
8 return itertools.izip(*iters)
9
10 photos = []
11 for root, dirs, files in os.walk('.'):
12 photos = [i for i in files if i.endswith('JPG')]
13 photos.sort()
14
15 for i, pair in enumerate(iwalkByN(photos, 2)):
16 print 'convert -morph 28 %s %s %02d-%%02d.jpg' % (pair[0], pair[1], i)
This will output a script:
convert -morph 28 IMG_0001.JPG IMG_0002.JPG 01-%02d.jpg
convert -morph 28 IMG_0002.JPG IMG_0003.JPG 02-%02d.jpg
which you can run w/ GNU parallel on a multi-core system:
parallel -j2 < convert-morph.sh
Lastly, to combine all of these into a WebM video, you can use MEncoder (remember to set FPS appropriately):
mencoder mf://??-??.jpg -mf fps=30:type=jpg -ovc lavc -oac lavc -of lavf -lavfopts format=webm -lavcopts threads=4:acodec=vorbis:vcodec=libvpx -ffourcc VP80 -o output.webm
or ffmpeg (you need to mangle the filenames involved):
cat $(find . -name '*jpg') | ffmpeg -f image2pipe -vcodec mjpeg -i - -r 30 -vpre libvpx-720p -quality good -threads 3 -an -f webm -y output.webm
Using a Webcam
If you've a Webcam that supports Linux UVC, you can use ffmpeg w/ the device directly. E.g.:
MJPEG
MJPEG saves a full JPEG image for each frame of video (no key frames). This takes a lot of space, and is lossy, but provides significantly better quality over other keyframe-oriented codecs, especially if you want to encode to another codec later.
# qmin indicates best frame quality (1 is best)
# qmax indicates worst frame quality
ffmpeg -f video4linux2 -s 1600x900 -r 5 -i /dev/video0 -vcodec mjpeg -qmin 2 -qmax 5 `time-stamp`.avi
XviD
XviD and other key frame-oriented lossy formats are unsuitable for recording from streams, as these codecs perform best with multi-pass encoding and you lose significant quality transcoding if you do any post-processing. However, you will use the least amount of space.
ffmpeg -f video4linux2 -s 1600x900 -r 5 -i /dev/video0 -vcodec mpeg4 -qmin 2 -qmax 5 `time-stamp`.avi
Lossless H.264
Lossless H.264 is, well, lossless. It uses significantly much more CPU than Huffman encoding/other lossless codecs, but also saves much more space. Preferred.
# `locate ffpreset` to see x264 presets
# http://rob.opendot.cl/index.php/useful-stuff/ffmpeg-x264-encoding-guide/#comment-14952
# order of bitrate: ultrafast, fast, medium, slow, slower, max
ffmpeg -f video4linux2 -s 1600x900 -r 5 -i /dev/video0 -vcodec libx264 -vpre lossless_fast -threads 0 `time-stamp`.avi
Poor-mans tone mapping
LDR tonemapping (aka Local Contrast enchancement in digiKam) attempts to bring out detail in shadows and lower blow-outs in bright areas. To do it with a video, compile the command-line tool, create a default settings file, and run:
parallel -u 'echo {}; ~/sys/tonemap/tonemapping ~/sys/tonemap/default.tnp {} {}.tonemapped && mv {}.tonemapped {}' ::: *.JPG