ネットワークカメラ

Raspberry Piで画像を取り込みたいと思った時に、それを実現する方法は色々とある。専用のカメラモジュールが用意されているし、以前に書いたようにUSBカメラを接続してキャプチャする事もできる。

監視用によく使われているAxisのネットワークカメラがたまたま手元に来たので、Raspberry Piでできるだけ簡単にネットワークカメラの画像を取り込む方法について試してみた。

AxisのネットワークカメラはWebサーバを内蔵しているので、ブラウザでアクセスするだけで映像をモニタする事ができるし、設定によってモニタ画面のボタンをマウスでクリックした時にその画像を保存する事ができる。と言うことはRaspberry PiでネットワークカメラのWebサーバにアクセスして、ボタンをクリックした時のCGIを実行できれば同じことができるはず。

まずはその前に、モニタ画面でボタンをクリックした時にRaspberry Piへ画像を送れるようにしてみる。FTPを使用するので、Raspberry PiにFTPサーバがインストールされていない場合は

$ sudo apt-get install vsftpd

で最初にインストール。
デフォルトではanonymousログインのみで書き込み禁止になっているので、/etc/vsftpd.conf ファイルを編集してanonymousを禁止、ローカルユーザによるログインと書込みを可にする。

anonymous_enable=NO
local_enable=YES
write_enable=YES

設定ファイルを編集したらサービスを再起動

$ sudo service vsftpd restart

カメラ画像の転送先フォルダも作成しておく。ここでは「camera」とした。

Axisネットワークカメラのイベント設定はアクションルールとレシピの二つに分かれていて、前者は何をイベントとして受け付けるのか、後者はイベントを受け付けた時の動作を設定する。従ってブラウザのモニタ画面でボタンを押された時に画像をFTPサーバへアップロードする場合は、アクションルールに「マニュアルトリガ」、レシピに「FTP転送」を設定する事になる。

スクリーンショット 2014-12-08 11.56.24

スクリーンショット 2014-12-08 11.43.31

この設定をネットワークカメラに保存して、モニタ画面のトリガボタンをON/OFFするとRaspberry Piに画像が転送される事を確認。これが上手く行ったら、あとはトリガボタンがON/OFFされた時に実行されるCGIを、Raspberry Piから直接叩けば良い。

トリガONの時は

カメラのIPアドレス/axis-cgi/io/virtualinput.cgi?action=6:/

が実行されて、OFFの時は

カメラのIPアドレス/axis-cgi/io/virtualinput.cgi?action=6:\

が実行される。

pythonでCGIを実行するのはurllibモジュールを使用すれば良いのだが、認証が必要になるのでそこがちょっとだけ面倒。予め認証用のオブジェクトを作っておき、それをurllibモジュールに登録しておく必要がある。

ネットワークカメラの画像をFTP転送させるプログラムは以下の通り。IPアドレスやカメラのユーザ名、パスワードは適宜変更する。

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

from urllib import request
from urllib import parse

class camera():
    def __init__(self, topurl, cgiurl, camuser, campass):
        passwd_mgr = request.HTTPPasswordMgrWithDefaultRealm( )
        passwd_mgr.add_password(None, topurl, camuser, campass)
        handler = request.HTTPDigestAuthHandler(passwd_mgr)
        opener = request.build_opener(handler)
        request.install_opener(opener)
        self.cgi = topurl + cgiurl
    def save(self):
        trig_on  = parse.urlencode({'action' : '6:/'})
        trig_off = parse.urlencode({'action' : '6:\\'})
        request.urlopen(self.cgi + trig_on)
        request.urlopen(self.cgi + trig_off)

if __name__ == '__main__':
    netcam = camera('http://192.168.1.90/',
                    'axis-cgi/io/virtualinput.cgi?',
                    'root',
                    'xxxxxxxx')
    netcam.save()

実際のところpythonが動けばRaspberry Pi以外でもこのプログラムは動作するので、画像キャプチャだけならわざわざRaspberry Piを使う必要は無いし、カメラ単体に一定周期や動体検知で画像保存する機能もあるから、それだけで事足りる場合も多いだろう。

何かのセンサー類を使って、特定の条件で画像を取り込みたい。というネットワークカメラ単体では対応が難しいような要件であれば、役に立つかもしれない。

広告