監視カメラを用いたメールアラートシステムを開発してみる

日立製作所OSSソリューションセンタの横井です。

　[前回の記事](https://qiita.com/kazuhitoyokoi/items/e4da2dc1c39c0a11569e)では、TensorFlow.jsを用いた画像認識のフローの開発手順を紹介しました。今回は応用として、監視カメラと画像認識を連携させたメールアラートシステムを開発してみましょう。以下の図の様に、監視カメラの画像に不審者が写った際、自動でメールでアラートを送るフローを作成します。

![79f36cd3-d3d5-d63e-d77e-b1df41283549.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/b9c44e16-04d1-b38b-efe3-1a9f8597d69b.png)

# 開発するフロー
　以下の様なフローを開発します。このフローでは、定期的にウェブサーバから監視カメラの画像を取得し、左下の「元の画像」のノードの下に画像を表示します。その後、TensorFlow.jsノードを用いて画像認識を行い、認識結果と認識結果付き画像をそれぞれデバッグタブと「認識結果付き画像」のノードの下に表示します。

![8b23a90d-cf4d-86aa-b2fd-6f27fc5399d9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/6f554d57-c2e3-69dd-25a5-24deffd926e3.png)

　もし、画像認識にて人物(person)が写っていると判定された場合は、SendGridノードを用いて画像ファイルを添付したアラートメールを送信します。実際に監視カメラを準備するのは大変なため、ここではサンプルとして、神奈川県が川の水量を確認するために設置している[監視カメラの画像](http://www.pref.kanagawa.jp/sys/suibou/web_general/suibou_joho/html/camera/past0/p20102_0_6.html)を活用してみました。

　以降で本フローの作成手順を説明してゆきます。Node-RED環境は、[ローカルPC環境](https://nodered.jp/docs/getting-started/local)、[Raspberry Pi環境](https://qiita.com/tseigo/items/5da3cff1801c0cd586e4)、クラウド環境などを用意してください。

# 必要なノードのインストール
　Node-REDフローエディタの右上のハンバーガーメニューをクリックし、「パレットの管理」->「パレット」タブ->「ノードの追加」タブと遷移し、以下のノードをインストールします。

- [node-red-contrib-tensorflow](https://flows.nodered.org/node/node-red-contrib-tensorflow) : TensorFlow.jsを用いた画像認識を行うノード
- [node-red-contrib-image-output](https://flows.nodered.org/node/node-red-contrib-image-output) : フローエディタ上に画像を表示するノード
- [node-red-contrib-sendgrid](https://flows.nodered.org/node/node-red-contrib-sendgrid) : SendGridを用いてメールを送信するノード

# (1) 画像データを取得するフロー
　最初に、ウェブサーバから画像のバイナリデータを取得するフローを作成します。以下のフローの様に、injectノード(ワークスペースに配置すると名前が「タイムスタンプ」に変わります)、http requestノード、image previewノードを配置し、ワイヤーで接続します。

![59cc6697-0b57-1483-e4ef-ca2b14cfd335.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/3e742505-d515-1803-4845-fba9a6b08463.png)

　その後、http requestノードをダブルクリックして、ノードのプロパティ設定を変更します。

## http requestノードのプロパティ設定
　http requestノードのプロパティ設定画面にあるURLに、監視カメラの画像のURLを貼り付けます(Google Chromeでは、画像の上で右クリックすると現れるメニューから「画像アドレスをコピー」を選択すると、画像をURLがクリップボードへコピーされます)。また、出力形式として「バイナリバッファ」を選択します。

![500bfd7e-2640-d885-fe93-e72442bf66f4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/4a9d9d9c-0b4b-14bc-0c48-568b76d4edbd.png)

## 画像データを取得するフローを実行
　フローエディタ右上のデプロイボタンをクリックした後、injectノードの左側のボタンをクリックします。すると、injectノードからワイヤーを通してメッセージがhttp requestノードに送られ、監視カメラの画像を提供するウェブサーバから画像を取得します。画像データを取得後、バイナリ形式のデータを含むメッセージがimage previewノードに送られ、image previewノードの下に画像が表示されます。

![9fc00c1e-99ea-2833-ff9a-96d6dac2a6b3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/3948744b-5ba9-f1c7-10dd-1ffdbb6de74b.png)

 右下に監視カメラが撮影した川の画像が表示されましたね!

# (2)取得した画像データに対して画像認識を行うフロー
　次に取得した画像に何が写っているかを分析するフローを作成します。cocossdノードと、debugノード(配置すると名前がmsg.payloadに変わります)、2つ目のimage previewノードを追加で配置します。その後、http requestノードの右側の出力端子とcocossdノードの左側の入力端子、cocossdノードの右側の出力端子とdebugノード、cocossdノードの右側の出力端子とimage previewノードの左側の入力端子をそれぞれワイヤーで接続します。これによって、監視カメラ画像のバイナリデータがcocossdノードに送られ、TensorFlow.jsを用いた画像認識が行われた後、物体名をdebugノードで表示し、画像認識結果付き画像をimage previewノードで表示します。

![8877b07e-3391-394a-d205-8e43041be110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/ed028af3-ea13-c02c-9d49-df09ed8b3c6d.png)

　cocossdノードは、変数msg.payloadに物体名、変数msg.annotatedInputに画像認識結果付き画像のバイナリデータを格納する仕様になっています。そのため、画像の表示に用いるimage previewノードはダブルクリックをして、ノードプロパティ設定を変更する必要があります。

## image previewノードのプロパティ設定
　image previewノードはデフォルトで変数msg.payloadに格納された画像データを表示します。ここでは、このデフォルト変数をmsg.annotatedInputに変更します。

![8275dd08-aee6-b9ab-338a-05799bce1b95.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/1c868367-8a9d-c1c4-2e77-6b9fe95c4bd7.png)

## injectノードのプロパティ設定
　1分毎にフローを定期実行するため、injectノードのプロパティも変更します。繰り返しのプルダウンメニューで、「指定した時間間隔」を選択し、時間間隔として「1分」を設定します。また、デプロイボタンを押した後、すぐに定期実行処理を開始したいため、「Node-REDの起動後、0.1秒後、以下を行う」の左側のチェックボックスをオンにします。

![74583f93-e2e9-f6ad-aec0-d0203f823bfb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/5517da41-d050-3c94-17bf-27d98856824c.png)

## 画像認識を行うフローを実行
　デプロイボタンを押すと、すぐにフローの処理が実行されます。監視カメラに人物(著者本人)が写ると、右側のデバッグタブに"person"という画像認識結果が表示されます。またimage previewノードの下には、オレンジ色の四角でアノテーション付けされた画像が表示されます。

![fb7c4f78-a6ef-dbbf-0235-468748f2f6e5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/9685b9d5-acf5-2ea2-275a-b3ba21892d23.png)

# (3)監視カメラに人物が写った時に、メールを送信するフロー
　最後に、画像認識結果の物体名が"person"だった時に、アノテーション付き画像をメールで送付するフローを作成します。cocossdノードの後続のノードとして、条件判定を行うswitchノード、値の代入を行うchangeノード、メールを送信するsendgridノードを配置し、それぞれのノードをワイヤーで接続します。

![71a0474f-d7b3-663a-899d-303bfb170b32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/e31ba301-22d8-845c-dba3-233693f58258.png)

　その後、各ノードのプロパティ設定を変更します。

## switchノードのノードプロパティ設定
  msg.payloadに"person"という文字列を含む場合のみ、後続のフローが実行されるように設定します。それを実現するには、条件「==」の比較文字列(azの右側)に"person"を入力します。

![a939b03e-9c6b-bd2b-596d-2604148ca1f0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/f769b6d3-9d80-c9f4-cca7-a09e30239907.png)

## changeノードのノードプロパティ設定
　認識結果付き画像をメールに添付するため、変数msg.annotatedInputに格納されている画像データを変数msg.payloadへ代入します。まず「対象の値」の右側の「AZ」のプルダウンメニューを開き「msg.」を選択します。その後、右側のテキストエリアに「annotatedInput」と入力します。

![9346c9cd-41ef-3b77-2015-41d1845f75d2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/fb99b867-5e14-4d78-abea-09d00092d803.png)

　「AZ」をクリックすると表示されるプルダウンメニューで「msg.」に変更することを忘れることで、フローが上手く動かないことがよくありますので、「msg.」になっているか再度確認しましょう。

## sendgridノードのノードプロパティ
　[SendGridの管理画面](https://sendgrid.com/)から取得したAPIキー、送信元メールアドレス、送信先メールアドレスを設定します。

![0686f088-f48d-c927-2af9-99136050600b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/c3665ddc-e73f-2da1-25a0-441f7e036689.png)

　最後に、各ノードでどんな処理を行っているか分かりやすくするために、各ノードのノードプロパティを開き、適切な名前を設定しました。

## 監視カメラに人物が写った時に、メールを送信するフローの動作確認

　監視カメラの画像に人物が写ると、前のフローの実行確認の同様に、デバッグタブに画像認識結果が表示され、「認識結果付き画像」のimage previewノードの下の画像にオレンジ色の枠が描画され、人物を正しく認識されていることが分かります。

![f481fc2d-3107-cf55-cbf8-78dd0597828b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/a6a4f91a-038e-02ed-5bfd-12e2fe4cfbf2.png)

　その後、判定処理や代入処理、メール送信処理が上手く動作すると、スマホにはアノテーション付きの画像ファイルが添付されたメールが届きます。
<img width="300" alt="71baa452-43ac-3e9e-8fc2-b2e5b434882f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/b342f692-32e4-e32a-8c51-cd29c861aa7f.png">

# 最後に
　今回ご紹介した様なフローを用いて、Raspberry Piに接続したカメラを利用した、自宅の庭の簡易防犯システムを自分で構築することも可能です。また本格的には、[ONVIF](https://qiita.com/t-tkd3a/items/86ee8c92cb580c5bae7b)等のプロトコルに対応したネットワークカメラを用いて取得した画像データに対して画像認識を行うこともできそうです。

※ 本記事はThe Linux FoundationのサイトLinux.comに投稿した下記記事の和訳です。
https://www.linux.com/news/developing-an-email-alert-system-using-a-surveillance-camera-with-node-red-and-tensorflow-js/