RaspberryPiにつないだLogicool C270でインターホンのモニタを撮影し、呼び出し音に応じてスマホに写真をPUSHする
はじめに
この記事はオートロックマンション用不在時荷物受け取りシステムの開発記事です。
前回までに、RaspberryPiにつないだウェブカメラ(Logicool C270、以下C270)でインターホン音を検知し、スマホに通知し、さらにGoogle Calendarと連携して配達指定時間帯の場合はサーボモータを操作して解錠するところまでいった。 不在時受取システムとしての最低限の機能はできたわけだが、今回はそれに加えて、インターホン音が鳴ったらメッセージだけでなく、C270で撮影したインターホンモニタの写真も一緒に送ってみる。
この記事で述べることを具体的に列挙すると、
C270のカメラを使って撮影する
C270の露出を調整・固定してインターホンモニタに合わせる
C270のピントを調整する
となる。
なお、RaspberryPi 3B+、Python3.7.3を使っている。
何もせずC270でインターホンモニタを撮影する
Logicool C270は非常に安価なウェブカメラであることから、RaspberryPiと一緒に使っている人が多いようである。
ロジクール ウェブカメラ C270 ブラック HD 720P ウェブカム ストリーミング 小型 シンプル設計 国内正規品 2年間メーカー保証
- 発売日: 2010/08/20
- メディア: Personal Computers
今回は、昔買ったものが家に転がっていたのでそれを利用した。
デフォルト設定のC270はオート露出になっているため、画角内の輝度が大きく異なると思ったとおりに撮影できない場合がある。例えば、以下の画像は家のインターホンモニタをC270で撮影したものだが、モニタが周りに比べ輝度値が高いため、モニタが異常に明るく写ってしまっている。
どのような照明環境でもモニタ部分をキレイに撮影するには、露出を固定する必要がある。
C270を固定露出にする
以下の記事を参考しつつ設定した。
まず、現状のC270の設定を確認する。コマンドはv4l2-ctl --list-ctrls
だ。デフォルトでは以下のような設定である。
brightness 0x00980900 (int) : min=0 max=255 step=1 default=128 value=128 contrast 0x00980901 (int) : min=0 max=255 step=1 default=32 value=32 saturation 0x00980902 (int) : min=0 max=255 step=1 default=32 value=32 white_balance_temperature_auto 0x0098090c (bool) : default=1 value=1 gain 0x00980913 (int) : min=0 max=255 step=1 default=0 value=32 power_line_frequency 0x00980918 (menu) : min=0 max=2 default=2 value=2 white_balance_temperature 0x0098091a (int) : min=0 max=10000 step=10 default=4000 value=3840 flags=inactive sharpness 0x0098091b (int) : min=0 max=255 step=1 default=24 value=24 backlight_compensation 0x0098091c (int) : min=0 max=1 step=1 default=1 value=1 exposure_auto 0x009a0901 (menu) : min=0 max=3 default=3 value=3 exposure_absolute 0x009a0902 (int) : min=1 max=10000 step=1 default=166 value=671 flags=inactive exposure_auto_priority 0x009a0903 (bool) : default=0 value=1
今回注目すべきはexposure_autoとexposure_absoluteで、前者が露出のオート・固定を、後者が露出量を規定している。現状exposure_autoはvalue=3となっており、これはオート露出を表す。また、露出量はexposure_absoluteによるとvalue=671である。これらの値を固定露出(exposure_auto=1)、また露出量は任意の値に設定する。
pythonのスクリプト中でv4l2-ctlのコマンドを打つ場合は以下のようにsubprocessを使う。以下は露出を200に固定する例。
import subprocess cmd = 'v4l2-ctl -d /dev/video0 -c exposure_auto=1 -c exposure_absolute=200' ret = subprocess.check_output(cmd, shell=True) print(ret)
これで露出を固定できる。自分の環境でやると、なぜか設定後の露出量の値が設定値より5高い値になっていたが、特段問題ないので気にしない。
実際に撮影する際にはopencvを使うのが楽なのだが、設定後一度プログラムを再立ち上げしないと露光設定が反映されなかったり、不安定だった。結果として以下のようにVideoCapture(0)の前にコマンドを打てば、即座に反映されることがわかった。最後のDummyは、これがあったほうが設定の反映が安定していたので、とりあえず入れている。
import cv2 import subprocess # opencv設定 cmd = 'v4l2-ctl -d /dev/video0 -c exposure_auto=1 -c exposure_absolute=200' # 露光時間をマニュアル設定 ret = subprocess.check_output(cmd, shell=True) cam = cv2.VideoCapture(0) if cam.isOpened() is False: print("Camera cannot open") sys.exit() else: _,_ = cam.read() # Dummy # あとは好きに撮影する ret, frame = cam.read() # frameに画像データが入っている
上記のexposure_absoluteの値を任意に設定すれば、好きな露出設定で画像が取得できる。
例えば、下は部屋を真っ暗にした上でインターホンの通話ボタンを押すと出る青い画面を様々な露光設定で撮影した際の画像である。
結局、exposure_absolute=200とした。
C270のピントを調整する
よくよく上の画像を見てみると、文字がぼやけておりピントが合っていない。C270はSkypeなどのWeb通話を想定して作られているため、デフォルトでは1m程度離れた位置でちょうどピントが合うようになっているためだ。今回はインターホンから30cm程度しか離れていない場所から撮影しているため、ピントがずれている。そこで、C270のピントを手動調整する。
C270のピント調整は簡単で、まずは正面のカバーをマイナスドライバー等でパカッと外し、内部のネジを外すと基板及びレンズが見える。 レンズについている歯車のようなものがピントの調整機構になっており、手で回すとピントが調整可能である。デフォルトでは一部に接着剤のようなものがついているため、ドライバー等ではがせばレンズを手で回せる。
C270のピント調整の更に詳細は以下の記事に詳しい。
ピント調整をした結果が以下の通りである。わかりやすさのため、モニタ部分のみクロップしている。 文字部分が明らかに鮮明になった。
画像が取得できたら、jpgで保存する。画像ファイルをPushbulletでスマホにプッシュする方法は以下の記事で述べたとおりである。
以上の設定をしてC270で撮影したインターホンモニタをPushbulletでスマホへ通知すると、以下のような感じになる。
最後に
この記事では、Logicool C270を使って露出固定撮影をする方法、ピント調整をする方法と、それらを使ってインターホンモニタをキレイに撮影する方法を述べた。