Raspberry Pi + Motion + WebCamで動体検知を行う

Raspberry Piに接続したWebCamから映像を取得可能なパッケージはいくつか有名なものが存在するようだが、今回はMotionという動体検知を行うことのできるパッケージを用いて、WebCamの映像を取得してみる。

パッケージのインストール

apt-getから取得することができる

sudo apt-get install motion

設定

今回はMotionをデーモン起動させて常時稼働させる。設定ファイルは以下のように変更した。

# Image width
width 640
# Image height
height 480
# Maximum number of frames to be captured per second.
# フレーム数を大きくしすぎるとRaspberry Piで処理しきれなくなる
framerate 3
# Output 'normal' pictures when motion is detected
# 動体検知時に画像を出力しない
output_pictures off
# Use ffmpeg to encode movies in realtime
# 動体検知時に動画を出力しない
ffmpeg_output_movies off
# Make automated snapshot every N seconds
snapshot_interval 1
# Locate and draw a box around the moving object.
# 動体マーカ
locate_motion_mode on
# Target base directory for pictures and films
target_dir /var/www/html
# File path for snapshots (jpeg or ppm) relative to target_dir
snapshot_filename snapshot
# Restrict stream connections to localhost only
# ローカルホスト以外からのアクセスを許可する
stream_localhost off
# Restrict control connections to localhost only
# ローカルホスト以外からのアクセスを許可する
webcontrol_localhost off

サービスの開始

USBカメラを繋ぎ、認識されていることを確認する。

lsusb

Bus 001 Device 015: ID 0c45:62e0 Microdia MSI Starcam Racer

設定ができたらサービスを開始する。でも正常にサービス開始しない。

sudo service motion start
Apr 20 18:42:55 raspberrypi motion[1410]: Not starting motion daemon, disabled via /etc/default/motion ... (warning).

/etc/default/motionも変更しないといけないらしい。

sudo vi /etc/default/motion

# set to 'yes' to enable the motion daemon
start_motion_daemon=yes

再度、サービス開始。
今度はちゃんと開始された。

sudo service motion start

以下のエラーが発生する場合は、画像の出力先のパーミッションに問題ある場合があるので、パーミッションを変更する。

Apr 20 19:28:15 raspberrypi motion[7929]: [1] [ERR] [ALL] put_picture: Can't write picture to file /var/www/html/snapshot.jpg - check access rights to target directory
                                          Thread is going to finish due to this fatal error:
Apr 20 19:28:15 raspberrypi motion[7929]: [1] [ERR] [EVT] event_image_snapshot: Could not create symbolic link [snapshot.jpg]:

Raspberianをインストール後にすること

Raspberry PiにRaspberianをインストール後、まずすること。普段からDebianを使っている人は違和感ないのかもしれないが、RHEL系で生きているとDebian系の使い勝手が分からなくて苦しい。

ロケールの変更

ロケールを日本語に設定すると文字化けでうまく表示されないので、en_US.UTF-8.UTF-8のままでよいかも。

$ sudo dpkg-reconfigure locales

タイムゾーンの変更

タイムゾーンを東京に変更する。

$ sudo cp -p /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
$ sudo vi /etc/timezone
Asia/Tokyo

キーボードの設定

日本語キーボードに対応する。

$ sudo vi /etc/default.keyboard

# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="jp106"
XKBLAYOUT="jp"
XKBVARIANT=""
XKBOPTIONS=""

BACKSPACE="guess"

ランレベルの設定

デフォルトだとXWindowが立ち上がるが、これをランレベル3に変更する。

sudo systemctl set-default multi-user.target

固定IPアドレスを設定

Raspbrianのバージョンによって設定方法が異なる。

Raspbrian jessie

固定IPの設定は、/etc/network/interfacesではなく、/etc/dhcpcd.confに追記する。

$ sudo vi /etc/dhcpcd.conf

interface eth0
static ip_address=192.168.0.10/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

以下のコマンドをいろいろ試したけど、新しい設定が全く反映されない。

$ sudo service dhcpcd restart
$ sudo service dhcpcd reload
$ sudo service dhcpcd force-reload
$ sudo service networking restart
$ sudo service ifup@eth0 restart
$ sudo systemctl restart dhcpcd
$ sudo systemctl restart networking
$ sudo systemctl restart ifup@eth0

仕方ないので端末再起動。

$ sudo reboot

Raspbrian wheezy

固定IPの設定は、/etc/network/interfacesに追記する。

$ sudo vi /etc/network/intefeces

インストール直後には、DHCP設定となっているので、固定アドレスとする場合は以下のように変更する。

auto lo

iface lo inet loopback
iface eth0 inet static

address 192.168.0.2
netmask 255.255.255.0
gateway 192.168.0.1

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp

無線LANの設定

Raspberry Piに無線LAN接続する場合は、以下の手順で行う。今回は、PLANEXのGW-USNANO2Aを使用した。

  1. Raspberry PiのUSBポートに挿入
  2. wpa_passphraseコマンドを、/etc/wpa_supplicant/wpa_supplicant.confに出力する
  3. /etc/wpa_supplicant/wpa_supplicant.confに、認証方式などの情報を追記する

WPA2-PSK(AES)の場合は、以下の通りとなる。

]$ sudo wpa_passphrase SSID PASS_PHRASE >> /etc/wpa_supplicant/wpa_supplicant.conf
$ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf

country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
        ssid="SSID"
        #psk="PASS_PHRASE"
        psk=xxxxxxxxxxxxxxxxxxxxxxxxxxx
        proto=RSN
        key_mgmt=WPA-PSK
        pairwise=CCMP
        group=CCMP
}

無線LANインタフェースの状況を確認するためには、

iwconfig wlan0

識別できているSSIDの一覧を取得するためには、

iwlist wlan0 scan | grep SSID

                    ESSID:"guest"
                    ESSID:"test"
                    ESSID:""
                    ESSID:"free"
                    ESSID:""

以下のファイルも変更する。
wlan0インタフェースを自動起動設定とし、wlan1インタフェースの無効化している。

]
$ sudo vi /etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)

Please note that this file is written to be used with dhcpcd
For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

iface eth0 inet manual

auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
     wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

#allow-hotplug wlan1
#iface wlan1 inet manual
#    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

パッケージのインストール

必要なパッケージをインストールする。

$ sudo apt-get install chkconfig
$ sudo apt-get install screen
$ sudo apt-get install apache2
$ sudo chkconfig ntp off
$ sudo chkconfig apache2 on

パッケージの更新もしておく。

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo rpi-update

プロキシ環境でapt-getを実行する場合は、以下のファイルを変更する。

$ sudo vi /etc/apt/apt.conf.d/10proxy

追記内容は以下の通り。

Acquire::http::Proxy "https://192.168.x.x:8080";

Vimの起動モードを変更

Viで矢印キーを押したときにABCDと出てしまう問題は、VimをVi互換モードではなく通常モードで起動することで直る。

~/.vimrcに設定を保存できる。sudoでvimを使うときのために/root/.vimrcにも追記しておく。

$ vi ~/.vimrc

:set nocompatible
:set backspace=indent,eol,start
:set number

~/.vimrcに書ける便利な設定がいろいろあるみたい。

設定 内容
:set nocompatible 通常モード起動
:set backspace=indent,eol,start バックスペースキーの挙動を指定
:set number 行番号を表示

もしくは、Vimのインストールでも直る。

$ sudo apt-get install vim

Raspberry piがRead-Only Filesystemになってしまったときの対処法

Raspberry piの設定ファイルを書き換えても再起動すると、元の内容に戻ってしまい変更が反映されない。

pi@raspberrypi ~ $ dmesg | egrep "readonly|read-only"

[    2.386594] mmc0: host does not support reading read-only switch, assuming write-enable
[    2.526799] EXT4-fs (mmcblk0p6): INFO: recovery required on readonly filesystem
[    3.242388] EXT4-fs (mmcblk0p6): orphan cleanup on readonly fs
[    3.370433] VFS: Mounted root (ext4 filesystem) readonly on device 179:6.

dmesgで見ると、ファイルシステム全体がReadonlyになっていて、これがファイルがうまく保存されない原因のようだ。起動中にSDカードを抜き出したり、電源を落としたときにファイルシステムが壊れたか。

recovery required on readonly filesystem

というわけでさっそく修復してみる。fsckコマンドで修復してみるも、既にマウントされているのでコマンド実行できないと怒られる。とりあえず早く修復して別の作業に取り掛かりたいので、カーネル起動オプション設定ファイル「cmdline.txt」に、fsckを毎回起動時に実行する設定を追記し、Raspberry Piを再起動。

fsck.mode=force

fsckが走ってとりあえず修復。よかった。