Raspberry Piに接続されたUSBカメラをIoT化して遠隔制御する(同ネットワーク内のみ)

師匠の誕生日プレゼントに作製している畑監視システムだが,カメラの制御には色んな手段があると考えている.その手段の一つとして,PythonのWebObを使用して,Webブラウザで撮影リクエストを送信し撮影するためのメモ.今回のメモは同ネットワーク内に接続されているスマートフォンやPCからの制御のみを実現するものであり,外部ネットワークから制御するためには,Raspberry PiのローカルIPアドレスを固定し,ルータの設定で特定のポートを開放し,Raspberry PiのローカルIPアドレスに関連付ける必要があるが,それは後々トライする.今回は,とりあえず同ネットワーク内のみ.

背景

畑を遠隔から監視するシステムの構築を目指している.
www.eletech.work
pythonのWebObというパッケージを使用することはこれを実現するための一つの手段であり,そのインストール手順は別の記事でメモを残している.
www.eletech.work
今回は,WebObを使用して,Raspberry Piとは別のデバイス(スマートフォンやPC)でUSBカメラを制御する(撮影する)ためのプログラムのメモ.

使用機器

使用した機器は以下の通り.師匠から送られてきたQuick Pro 4000で撮影される画像の解像度が低い&ピントが合わないためとりあえず手持ちのUSBカメラに変更した…

  • Raspberry Pi 2 model B
  • UCAM-DLV300TBK


Raspberry Pi 3 Model B V1.2 (日本製) 国内正規代理店品


【2009年モデル】ELECOM WEBカメラ 300万画素 1/4インチCMOSセンサ マイク内蔵 片耳ヘッドセット付 ブラック UCAM-DLV300TBK

プログラムの作成

作成したプログラムは以下の通り(python3).

import cv2 #openCV
from webob import Request, Response  #WebOb 

# make web page using html
html = """
<h1>Farm Watching System</h1>
<img src="image.jpg">
<form method="post">
<input type="submit" name="button" value="Request" style="width:150px; height:50px; font-size:30px">
"""

class WebApp(object):
    def __call__(self, environ, start_response):
        req = Request(environ)
        if req.path == '/image.jpg':
            #--------------------------capture using camera-------------------------#
            cap = cv2.VideoCapture(0)
            r, img = cap.read()
            cv2.imwrite('image.jpg', img)
            cap.release()
            cv2.destroyAllWindows()
            print ("capture\n")
            #----------------------------------------------------------------------------------#
            bin_data = open('image.jpg', 'rb').read()
            resp = Response(bin_data, content_type='image/jpeg')
        elif req.path == '/':
            button = req.params.get('button', '')
            resp = Response(html)
        else:
            resp = Response()   #error
        return resp(environ, start_response)

application = WebApp()

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    port = 8080
    httpd = make_server('', port, application)
    print('Serving HTTP on port %s...' % port)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt: #Ctrl + C
        print ("finish\n")

プログラムの実行と動作確認

ターミナルでプログラムを実行.

pi@raspberrypi:~ $ sudo python3 farm_camera.py farm_camera
Serving HTTP on port 8080...

Serving HTTP on port 8080...と表示されたら準備完了.スマートフォンやPCでブラウザを開く.今回はとりあえずPCで試す.PCのブラウザを開き,URLとしてRaspberry Piに割り当てられているIPアドレス+:8080と指定する.

f:id:EleTECH:20190205232844p:plain
Raspbeery Piへのアクセス
すると,作成したhtmlのページを見ることができる.Webページを開くときに送信されるリクエストでUSBカメラで撮影された画像と共に,リクエストボタンが生成されている.私の愛娘の大好きな犬のぬいぐるみが見えた.
f:id:EleTECH:20190205233041p:plain
ブラウザの画面
カメラの位置をちょっと調整して,リクエストボタンで再度撮影できるか確認すると,無事動作して安心.愛娘の犬のぬいぐるみの横顔も頂きました.
f:id:EleTECH:20190205233401p:plain
リクエストボタンの確認

今後

今回はとりあえず同ネットワーク内につながっているデバイスから遠隔制御するプログラムを作製したが,これを外部ネットワークからでも出来るように今度は試そうと思う.あと,畑監視システムではカメラでの撮影だけでなく,温湿度センサをRaspberry Piに接続することを考えており,これも順次進めていく.

参考

以下の書籍の内容を参考にさせて頂きました.

  • 松原 拓也,"作って楽しい!ラズパイ・プログラミング",日経BP社,東京,2016.


作って楽しい! ラズパイ・プログラミング(日経BPパソコンベストムック)