ラズパイでカメラモジュールを使って定点観測(タイムラプス, コマ抜き撮影, Raspberry Pi)



この記事ではRaspberry Pi (以下、ラズパイと呼ぶ)でカメラを使えるようにし、数分おきに写真撮影をしてそれを動画にするまでの方法を説明していく。iPhoneでは「タイムラプス」、Androidでは「コマ抜き」という低速度撮影の機能にあたる。
ベランダで菜園している植物の成長を、定点観測で撮影してみたら面白そうと思ったのがきっかけだった。

なお、ラズパイの基本的な設定は既にできているものとして操作はMacのターミナルからSSHでログインして行っていく。
Raspberry Pi のセットアップ!モニター、キーボードなしでMacからSSH

今回ラズパイは Raspberry Pi3 Model B+ を使用したが、最新の Raspberry Pi4 でも同じ設定で動作すると思う。







ラズパイのrootログイン設定


カメラを設定する上で、ラズパイのrootになる必要があった。しかし初期状態のラズパイにはrootにパスワードが設定されていないためrootにログインできない。

そこで次のコマンドでパスワードを設定することでrootにログインできるようになる。
$ sudo passwd root
ただし、rootにパスワードを与えることはセキュリティーホールになるため用途を見極めた上で行ったほうが良いだろう。

パスワードを設定する前の状態に戻したかったら次のコマンドで戻すことができる。
$ sudo passwd -l root



ラズパイの時刻設定


いつ撮影した写真なのかをファイル名に残せると便利だ。そこでラズパイの時刻合わせを行う。
時刻を手動で合わせてもよいがラズパイにはハードウェア時計が装備されていないため、いくら設定しても再起動するたびに時間はズレてしまう。毎回時刻を合わせするのは面倒なので、ラズパイの起動時にネット接続して自動で時刻を合わせるようにしておこう。

$ sudo vi /etc/rc.localexit 0 より前の行に timedatectl set-timezone Asia/Tokyo の一行を追記する。

ラズパイをリブートし、現在の時間と合っているか時計と確認しよう。
$ date
Tue Aug  4 09:12:40 JST 2020`




ラズパイにカメラを認識させる


それではいよいよカメラの設定だ。
今回ラズパイに接続するカメラモジュールは、Amazonで購入したHiLetgoの OV5647 カメラモジュール というものだ。なんと1000円以下という安さ。



カメラの接続は差し込むだけなので説明は省く。ラズパイにカメラを接続したら次の手順へ進もう。
$ sudo raspi-config5 Interfacing OptionsP1 Camera へと進み Yes を選択してカメラを有効にする。
再起動後、vcgencmd get_camerasupported=1 detected=1 と表示されればカメラの接続に成功している。



カメラで画像を撮影してみる


カメラの設定ができたら、さっそくラズパイカメラで撮影してみよう。
撮影は RaspbianOS に標準で実装されている raspistill というコマンドを使って撮影できる。
$ raspistill -o photo.jpg

とても簡単だ。

ところで私のラズパイにはモニターがないので、画像を確認したい場合はMacから scp コマンドを使ってダウンロードして確認する。
$ scp pi@0.local:~/photo.jpg .




ファイル名に日付を追加


先ほどラズパイに時間の設定をしたので、せっかくなので撮影したファイル名に時間を追記してみたい。
$ raspistill -o `date "+%Y%m%d_%H%M%S"`.jpg

すると 20200804_092756.jpg のようなファイル名を保存できるはずだ。



ファイルサイズ(画質)の変更


raspistill で撮影した写真は、デフォルトではファイルサイズが2.4MBと大きめだ。
画像サイズは次のようにして変えられるので、必要に応じて指定すると良い。
raspistill -w 480 -h 360 -o `date "+%Y%m%d_%H%M%S"`.jpg

この場合、2.4MBから119kBまで圧縮できた。



Macから写真撮影してプレビューする


写真撮影のたびに毎回ラズパイにsshでログインして撮影し、scpでファイルをダウンロードして確認というのはあまりに面倒だ。そこでMac側の操作一発で写真撮影から写真表示までできるシェルスクリプトを書いてみた。
#!/bin/bash

HOST='pi@0.local'
DIR='photo'
FILE=`date "+%Y%m%d_%H%M%S"`.jpg

ssh ${HOST} "raspistill  -w 960 -h 720 -co 20 -awb shade -ex auto -o ${DIR}/${FILE} ; exit"
scp ${HOST}:${DIR}/${FILE} ${DIR}/
ssh ${HOST} "rm -f ${DIR}/${FILE}"
open ${DIR}/${FILE}

これを改造してディレクトリも自動生成できるようにすると、もっと便利かもしれない。



コマ撮り撮影(タイムラプス)


写真の撮影に慣れたところで、いよいよコマ撮り撮影(タイムラプス)をやってみよう。
なんと raspistill コマンドには、タイムラプスのオプションが装備されているのでそれを使っていく。

$ raspistill -t 30000 -tl 2000 -o photo/image%04d.jpg

これは2秒おきに30秒間だけ写真を撮るという命令だ。-t-tl にはミリ秒で指定することに注意する。
ちなみに1時間は3600秒、24時間だと86400秒。秒をミリ秒に変換したい場合は1000をかければ良い。



SSHがログアウトしてもプログラムを継続実行させる


通常sshでログインしてシェルを実行すると、ログアウトした時にそのシェルは停止してしまう。
そこで nohup を使う。
nohup はsshをログアウトしてもシェルを実行し続けてくれるコマンドだ。nohupRaspbianOS に標準で実装されているのでインストールの必要はない。
$ nohup raspistill -t 86400000 -tl 30000 -w 960 -h 720 -co 20 -awb shade -ex auto -o tomato/image%04d.jpg > tomato/out.log &


30秒おきに1日撮影する設定で、そのほかのオプションは色合いとかの調整をしている。
コマンドの最後の & はバックグラウンドで実行することを意味する。

sshを exit してから再度ログインして、シェルが継続しているか $ ps x などで確認しよう。
nohup で実行中のシェルを止めたい時は、 $ ps x でプロセスIDを調べてその番号を kill すればよい。
$ ps x
  PID TTY      STAT   TIME COMMAND
 1202 ?        Ss     0:00 /lib/systemd/systemd --user
 1205 ?        S      0:00 (sd-pam)
 1418 ?        Sl     0:00 raspistill -t 86400000 -tl 30000 -w 960 -h 720 -co 20
 1464 ?        S      0:00 sshd: pi@pts/0
 1467 pts/0    Ss     0:00 -bash
 1479 pts/0    R+     0:00 ps x

$ kill 1418




avconvで動画撮影


それでは最後に撮影したコマ撮り写真をつなげて動画にしてみよう。
それを実現するためには avconv が便利だろう。次のコマンドで avconv をインストールする。
$ sudo apt install libav-tools
もしインストールに失敗するようだったら$ sudo apt updateを一度実行してから再度試すとうまくいくかもしれない。(私の場合はこれでようやくインストールできた。)
$ avconv -r 30 -i tomato/image%04d.jpg -vcodec libx264 -vf scale=960:720 tomato/timelapse.mp4

こんな感じで撮影した写真をつなげて動画を作成できる。



定点観測してみた



システムの設定はそれほど大変ではなかったのだが、カメラの位置調整で日が暮れそうな時間までかかってしまった。やはりその場で確認できるプレビュー画面がないと不便だ。

実際にベランダで定点観測してみた。

このカメラモジュールどうもフィルムカメラっぽい色合いになる。


ちなみにトマトの動画はMac上のffmpegを使ってcropしてある。
$ ffmpeg -i tomato.mov -vf crop=w=480:h=320 tomato.mp4

映像に面白みはないが、とりあえず動作テストには成功ということで。
プログラミング技術と撮影技術は、まったく別ものだと痛感した。



定点観測の再挑戦



他のトマトの実が赤付きそうなのでもう一度定点観測してみる。
次は10日間、5分間隔で撮影するプログラムだ。
$ nohup raspistill -t 864000000 -tl 150000 -w 960 -h 720 -co 20 -ex backlight -o tomato-20200806/image%04d.jpg > tomato-20200806/out.log &

計算が正しければ2880枚の写真を撮ることになる。
上手く撮れれば記事に追記する予定。




raspistillのオプション


raspistill にはいろいろな機能があるので一度ヘルプを表示して確認しておくと良いだろう。

$ raspistill --help

parameter mean
-w Set image width <size>
-h Set image height <size>
-q Set jpeg quality 0 to <100>
-r Add raw bayer data to jpeg metadata
-o Output filename <filename> (to write to stdout, use '-o -'). If not specified, no file is saved
-l Link latest complete image to filename <filename>
-v Output verbose information during run
-t Time (in ms) before takes picture and shuts down (if not specified, set to 5s)
-th Set thumbnail parameters (x:y:quality) or none
-d Run a demo mode (cycle through range of camera options, no capture)
-e Encoding to use for output file (jpg, bmp, gif, png)
-x EXIF tag to apply to captures (format as 'key=value') or none
-tl Timelapse mode. Takes a picture every ms. %d == frame number (Try: -o img_%04d.jpg)
-fp Run the preview using the still capture resolution (may reduce preview fps)
-k Wait between captures for a ENTER, X then ENTER to exit
-s Wait between captures for a SIGUSR1 or SIGUSR2 from another process
-g Draw preview to texture instead of using video render component
-gc Capture the GL frame-buffer instead of the camera image
-set Retrieve camera settings and write to stdout
-cs Select camera . Default 0
-bm Enable 'burst capture mode'
-md Force sensor mode. 0=auto. See docs for other modes available
-dt Replace output pattern (%d) with DateTime (MonthDayHourMinSec)
-ts Replace output pattern (%d) with unix timestamp (seconds since 1970)
-fs Starting frame number in output pattern(%d)
-rs JPEG Restart interval (default of 0 for none)
-gps Apply real-time GPS information from gpsd as EXIF tags (requires libgps.so.22)
-sh Set image sharpness (-100 to 100)
-co Set image contrast (-100 to 100)
-br Set image brightness (0 to 100)
-sa Set image saturation (-100 to 100)
-ISO Set capture ISO
-vs Turn on video stabilisation
-ev Set EV compensation - steps of 1/6 stop
-ex Set exposure mode (see Notes)
-fli Set flicker avoid mode (see Notes)
-awb Set AWB mode (see Notes)
-ifx Set image effect (see Notes)
-cfx Set colour effect (U:V)
-mm Set metering mode (see Notes)
-rot Set image rotation (0-359)
-hf Set horizontal flip
-vf Set vertical flip
-roi Set region of interest (x,y,w,d as normalised coordinates [0.0-1.0])
-ss Set shutter speed in microseconds
-awbg Set AWB gains - AWB mode must be off
-drc Set DRC Level (see Notes)
-st Force recomputation of statistics on stills capture pass
-a Enable/Set annotate flags or text
-3d Select stereoscopic mode
-dec Half width/height of stereo image
-3dswap Swap camera order for stereoscopic
-ae Set extra annotation parameters (text size, text colour(hex YUV), bg colour(hex YUV), justify, x, y)
-ag Set the analog gain (floating point)
-dg Set the digital gain (floating point)




参考サイト


https://www.raspberrypi.org/documentation/raspbian/applications/camera.md

raspistill - Raspberry Pi Documentation
Time-lapse - Raspberry Pi Documentation
Raspberry Pi メモ (23) - カメラモジュールの使い方
RaspberryPi(pidora)の時間のズレを治す ntpdateの自動実行を設定 | Astro.jp
Raspberry Piでカメラが認識しない際の対処法 - Qiita
Raspberry Pi用カメラモジュール | | Physical Computing FAQ& Tutorial
raspistill コマンドを使った写真撮影 - bnote
dateコマンドでバックアップファイル作成時にファイル名に日付_時間を付ける (LinuxとWindows用) - Qiita
サーバの接続切れてもコマンドを実行する ~ nohup - 忘れないようにメモっとく
ログアウトした後もプログラムの処理を続ける?(コマンド実行時にnohup)
ログアウトしてもバックグラウンド ジョブを継続する方法
ラズパイ3Bおよび3B+に最適なACアダプター 5V/3.0A USB Micro-Bコネクタ出力 - SWITCH-SCIENCE
ラズパイカメラのピントを近くに合わせる方法 | そう備忘録


あなたにおすすめ