36.防犯カメラ-2(BOUHAN-TEC) (2021.9.16-2023.11.17)

28.人感・防犯カメラ」で基本的となる防犯カメラを作りました。しかし、色々と不満な点も残るため、更なるグレードアップを図りたいと思います。防犯カメラは広義の意味で監視カメラとし、名称も「(BOUHAN-TEC」と命名しました。ハードウェアは前回のものを使用しますが、監視カメラとして隠密的な運用するために、最終的には例えばマスコット人形等のようなものの中にでも収めたいと考えています。

BOUHAN-TECの解説の前書きとして、環境のセットアップ作業をまとめました。実はプログラム開発中にOSが異常を来たして、操作中等にメニューバーが消えてしまう現象が多発するようになったのです。決定的な回避策が見つからなかったため、環境設定のおさらいも兼ねてOSの再インストールを実施しました。作業手順は次の通りです。
1.OSの再インストール → Raspberry Pi Imagerを使ってMicroSDカードにOSをインストールする。
2.RasPiにMicroSDカードを挿入して電源を入れる。
3.起動したら初期設定を行う。(順にウイザードが表示される)
  ・Set CountryでJapanを選択(他は自動設定される) → Next
  ・Change Passwordでパスワードをセット(何もセットしないと初期設定のRaspberryとなる) → Next
  ・Set Up Screenでデスクトップ周囲に黒い枠があったら、This screen ・・・の前のチェックボックスにチェックを入れる。 → Next
  ・Select WiFi Networkで接続したいアクセスポイントを選択する。 → Next
  ・WiFiのパスワードを入力する。 → Next
  ・WiFiに接続するとアップデートを求められるのでNextで進む。必要無ければSkipで進む。
  ・アップデートが終わるとSetup Completeダイアログが出るので、Restertをクリックして再起動する。
4.更にアップデートと日本語化(fcitx-mozcのインストール)を実施する。  
  sudo apt-get update
  sudo apt-get upgrade
  sudo apt-get install fcitx-mozc
5.メインメニューからRaspberry Piの設定 → インターフェースと進み、必要な機能の追加を行う。
  私の場合はシリアルポートとリモートGPIO以外は全て有効に設定。OKで設定を閉じたら再起動する。
6.CV2をインストールする。
  sudo pip3 install opencv-python
  sudo apt-get install libatlas3-base
7.numpyのアップグレードとTkinterを利用してCanvasに表示するためのライブラリをインストールする。
  pip3 install -U numpy
  sudo apt-get install python3-pil.imagetk

BOUHAN-TECの全体像は写真の通りです。左がRasPi本体とケースに固定したカメラ、外部制御回路等です。右奥の投光器の手前にあるのが警告装置で、透明アクリルの上にスピーカー、アンプ、警告ランプを設置しています。アンプはステレオで単独でも利用できるため、実験等に活用するつもりです。BOUHAN-TECシステムとしてはこれが1つの完成形になります。ただし、監視カメラとしては更に進んだシステムを考案中で、引き続き開発を進めたいと考えています。

今回はソフトウェアの強化がメインです。現在考えられる最大の課題は、プレビュー画面がcameraモジュールの制限で自由なコントロールが利かない点です。一応プレビューは表示しますが、操作パネルとの一体感は無く、リモートPC側には表示もされません。これでは不便なので、操作パネルウインドウ上にプレビューを表示するようにしたいと思います。色々調べてみましたが、どうもこのままでは実現できそうに無いため、以前に断念したCV2モジュールを使って実現を目指すことにしました。TkinterのCanvasに表示するのが現実的な対処ですが、利用できそうなサンプルプログラムがなかなか見つかりません。かなりネットを調べてクラスを使った処理で実現できることがわかりましたが(実際プレビュー表示はできた)、私自身がクラスについてあまり理解しておらず、他の処理との兼ね合いもあって、クラスを使わない方法で実現しようと思います。いずれにせよ処理の根幹部分を全面的に作り直す必要があり、私にとってはかなりハードルの高いものになると覚悟しています。

例によってこの手のプログラム作成には、基本となる単純な処理での確認から始めます。その方が問題点も洗い出し易く、どのように処理すれば動作するか確認するのも楽になるからです。そこで比較的よく掲載されているサンプルを探して処理を確認することにしました。最終的にはCanvasに表示するのが目標ですが、まずは録画実験が先です。
CV2を使った録画サンプル

処理を確認すると、どうやら録画はパラパラマンガの要領で、1枚1枚フレーム画像を取り込んで、fps×秒数で規定した枚数のデータを取り込めば良いようです。恐らく再生時にはデータのfps値に従って録画時間だけ再生されるのでしょう。一方、Canvasへの普段のプレビュー画面の描画は、適当なディレイタイムを置いてフレーム画像を取り込んでは表示する作業を続ければ良いと思われます。つまりプレビューと録画の2つのパターンを用意すれば、初期の目的が達成されそうです。

改良作業は比較的順調に進んでいましたが、動作確認中に2点問題が発生しました。1点目は一般的に利用されているmp4のファイルが正常に作られないのです。一応ファイルは作られますが、VLCメディアプレーヤーで再生ができません。他のmp4ファイルは再生できたため、本システムが作るファイルに異常があるようです。CV2も実はバージョンアップされていて、現在はCV4となっています(importする場合はCV2のまま)。もしかするとPythonのバージョン等も関係するのかもしれません。この問題はいずれ追及するとして、aviファイルなら正常に保存されることがわかり、原因が判明するまではaviで進めることにします。mp4の場合はコーデックにmp4vを使いますが、aviの場合はDIVXを使用します。録画の際の設定部分を少し書き換えるだけなので、後に変更するのも手間ではありません。

2点目の問題は、録画時のCanvasの表示に異常が発生することです。録画ファイルを見る限りは正常なのですが、画面表示(Canvas上)では頻繁にフラッシュしてまともに見られません。よく見ると古い画像と新しい画像が混在して切り替わる妙な表示です。画像表示のメカニズムは、カメラから得られる画像を次々重ねる形でCanvas上に書き出します。このままでは際限なく重ね続けてしまうため、Pythonは参照されなくなった不要なデータを開放しようとします(ガーベージコレクション)。その過程でこのような不具合が発生すると考えられますが、プレビューでの表示は正常に行われていることから、なぜ同じような処理をしながらこちらで不具合が出るのかわかりません。一方で表示だけの問題なので、さほど支障があるわけではありません。無視しても良いのですが、気になるので何とか改善できないか試行錯誤中です。

この問題、その後色々トライしましたが、どうやら繰り返しCanvasに表示しても、すぐに消えてしまう現象が多発しているようです。たまたま表示が長く続いた時だけ目で認識できるので、連続して見るとフラッシュしているように見えるわけです。Canvasをcreateした後は、itemconfigで画像のみ書き換えるよう改良し、処理終了後はCanvas自体を厳密に消去しましたが、それでも症状が改善することはありませんでした。ネットの様々な情報とも考え合わせて、ガーベージコレクションが何らかの影響を及ぼしていると思えるのですが、Python(と言うよりもTkinterライブラリ?)のバグの可能性も疑われます。これ以上進展が見られそうに無いので、とりあえず保留にするしか無さそうです。

ところで、BOUHAN-TECは暗闇の中では赤外線カメラとして機能します。通常はこれでも目的は果たせるわけですが、ありきたりでは面白く無いので、暗闇でもカラーの鮮明画像を得る機能を持たせました。どうするかと言うと、モーション検知によって録画を開始した後、全録画時間(現在の設定では20秒)の1/2が過ぎたところでビデオライトを点灯するのです。つまり録画の始め半分の時間は赤外線によるモノクロ映像、残り半分の時間はカラー映像となるわけです。もっとも、侵入者に気付かれたく無い場合もあるでしょうから、あらかじめ点灯するか否かを選択しておきます。なお、自動録画では周囲が明るい中でライトを点灯しても意味は無いので、暗い環境でのみライトが点灯するように新たに照度センサーを追加しました(下の写真の左部分に見える青い基板)。設定では500ルクスを下回るとライト点灯が有効になります。ただし、手動で点灯する場合は周囲の明るさは無視します。手動点灯は主にプレビュー画面で周囲がやや薄暗くて見にくい時に役に立つ機能ですが、手動録画にも有効に使えると思います。

BOUHAN-TECには2つの通知機能が用意されています。1つはメール(E-Mail)としてメッセージと共に撮影した動画を添付して送信する機能、もう1つはLineにメッセージと最初の録画画像(静止画)を送信する機能です。受信したサンプルが次のもので、上がメールで下がLineです。操作パネルであらかじめどちらかを指定しておきます(初期設定ではメール)。

BOUHAN-TECで録画したデータの一例です。(注:aviファイル)
録画サンプル

最終的に操作パネルは次のようになりました。上部にメインとなるプレビュー画面(録画中は録画画面)、下部に操作ボタンやインジケーター類を表示します。通常は自動録画(モーション)待機状態になっていて、侵入者を検知すると録画に移行します。指定時間録画した後は自動録画待機モードに戻ります。操作部の中央の下辺りが空いていますが、実は起動直後、ここに「-準備中-」の赤い警告文字が点滅します。モーションセンサーが稀に起動直後に誤動作を起こすことがあるので、短時間の待機時間を置いています。この種のセンサーは通電直後に不安定になりやすいとのことで、念のための対策でもあります。

補足ですが、一般に多く出回っている人感センサーは安価に入手できますが、その分センサーとしてはやや大雑把なところがあります。明るい環境では頻繁に誤検知するし、設置環境によっては逆に検知して欲しい時に反応しない等、信頼性に欠ける面もあります。人感センサーの中には高精度のものもあり、温度センサーによる補正や複数のセンサーを組み合わせたりAIを取り入れる等、様々な技術を駆使して誤検知を防止しているようです。あまり情報は得られませんでしたが、高精度のセンサーは万単位のコストがかかります。センサーは機器の要でもあるので、できればより高性能なセンサーを導入したいところです。

<追記(2021.9.27)
録画時のプレビュー画面フラッシュの問題について補足します。試行錯誤しつつもなかなか成果がでませんでしたが、自然な処理の流れを作るために録画処理ループを改め、プレビュー表示と共に保存処理を行うようにすることで、問題を回避することに成功しました。元は録画時に必要な画像枚数を確保するために、処理の途中(関数内)でループさせていたのですが、この間はCanvasの更新ができなくなるようです。こうした途中ループを作らないように、関数内の処理はなるべく速く抜けるようにして、afterメソッドを使って関数外でループを作るようにするのがキモでした。ただし、プレビューと録画を同じループ中で実行すると一つ問題が起こります。プレビューでは意図的に適当なディレイをループ中に入れる必要があるのに対して、録画ではfps値に合わせて保存タイミングが適当に調整されるようで(ディレイが自動的に入る)、プレビュー用にと意図的に入れたディレイが重なると処理が遅れてしまいます。例えば1分録画するつもりが2分になったりするわけです。それを防ぐために、プレビューのディレイを限りなく小さくしなければなりません。

BOUHAN-TECではプレビュー用のディレイを100ms、fps値を10にして同じタイミングとしていましたが、これだと録画時間が想定よりもかなり延びてしまいます。そこでディレイの方を10ms(元の1/10)にしたところ、目標に近い時間で処理できるようになりました。ディレイは0が理想かと思いますが、とりあえずはこれで大丈夫だと思います。改良によりプログラムの要となる部分を見直すことで、別スレッドでの処理も不要となり、プログラムの構造自体はシンプルになりました。PythonでGUI系のプログラムを組む際は、安易に関数内でループを作らないよう注意しなければなりません。

これまで他の言語のGUI処理で、これほど苦労したことは皆無なので、PythonでのGUIは扱い辛いと感じます。そもそも意図的にループを作り出さないとGUIがまともに維持されないような仕様は、根本的に問題ではないかと感じます。プリント文等のように互換性の無い変更を平気で行ったり、afterやthreadのようにメソッドの引数の記述が異なっていたり、差別化を図るためか妙な表記が多いのもPythonの特長で、これだけクセが強いとプログラミング言語を変更することも検討しようかと考えるようになりました。ただ、Pythonのようなインタープリター言語はデバッグが容易なため、なかなか判断に迷うところでもあります。今後更に調査して、より良い道を模索したいと思います。

<追記(2023.11.6)
BOUHAN-TECに使用した人感センサーの調子が良くないため調べてみると、不定期にセンサー出力が0から1になっていることがわかりました。センサーを取り出して単独でテストすると異常は無いようですが、システムに戻すと誤動作をしています。電源が不安定なのかセンサーがノイズで誤動作するのか、センサー自体の不良も考えられるし、それとも更に別の原因なのか分かりませんが、これではまともな運用は不可能です。そこで、人感センサーを新たに複数個購入して、改めてテストすることにしました。

<追記(2023.11.17)
人感センサーを新たに入手したものに取り替えたところ、あっさりと誤動作が解消しました。センサーの単体不良のようです。不良と言っても、以前に製作したモーションセンサーライト等なら使えそうなので、調子が悪い個体は別の用途で活用したいと思います。1点注意点ですが、新たに購入したセンサーはトリガー用のジャンパーピンが付いていませんでした。一部の写真にはジャンパーピンが付いているし、レビューでも付いているらしきコメントがあるので、ロットや仕入れの都合で変わるのかもしれません。こうしたいい加減な商売もamazonでの特長で、実に困ったものです。

<追記(2023.11.25)
解消したかに見えたセンサーですが、何度もテストを行っていたら稀に誤動作が発生しました。やはり赤外線ライトの影響かと思いセンサーにフードをかぶせたら、今のところ誤動作は発生していません。完全に解消したかは分からないので、この先も注意する必要がありそうです。