岩舘電気の中の人が Raspberry Pi を使ってホワイトボード共有システムを作ってみた

　岩舘電気の中の人です。久しぶりの投稿となります。岩舘電気は IoTLT 一関の2019年度の活動を支援させていただくことになりました。それに併せて弊社で Raspberry Pi を使ったソリューションの例をご紹介したいと思います。

　皆さんの会社では、社員の出先管理をどのようにしているでしょうか。サイボウズのようなクラウドソリューションはあるものの、案外PCやスマホで出先を入力させるのは手間だったりします。

　弊社ではエンジニアの出先をホワイトボードに書いていくようにしていたのですが、エンジニアの部屋と離れたバックオフィスにも行先を連絡する必要があり、この連絡に内線電話を使っていました。絵に書くと下のような感じです。エンジニアは行き先をバックオフィスに電話したうえでホワイトボードに行き先を書き、電話を受けたバックオフィスの人もホワイトボードへの書き込みを行う必要があります。

![Raspberrypi導入前](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61220/c155ace7-43c0-6cca-1ee6-471dd357956a.png)


　ただこの仕組みは、ほんのちょっと出かけるにも毎回電話をかける必要があるため心理的な負担がありますし、バックオフィスの人が忙しくて「電話をもらったけどあとで予定を書いておこう」と思ってそのまま忘れてしまう、というようなこともあり得ます。何より情報の参照先がエンジニアとバックオフィスで別々であるというのは、情報のシングルインスタンスの原則からも外れています。

　これを解消するためにウエブカメラを設置し、次の図のような仕組みで解決しようと考えました。

![ウエブカメラ導入図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61220/42c381e6-2c4d-5c4d-a140-71467334bc69.png)


　実は一度市販のウエブカメラを使ってみたのですが、解像度に問題があったり、ライブ配信にするとストリームの数に制限があったりして結果がイマイチでしたので、Raspberry Pi とカメラモジュールで解決することにしました。

　とりあえず Raspberry Pi 3 とカメラモジュールを購入します。これが無いと始まりません。一般的なご家庭であれば Raspberry Pi や SD カードが余っていると思いますので適当に使いまわしてしまいましょう。さて Raspberry Pi が起動することが確認できたら入手後のおまじないです。

```
$ sudo apt-get update
$ sudo apt-get upgrade
```
　次にカメラモジュールをenable します。（方法は割愛します） ついでに apache も入れてしまいます。なお今回は画像を扱うため、VNC を enable にするかリモートデスクトップサービスを導入するとテストの際に楽です。ここではリモートデスクトップを導入してみます。

```
$ sudo apt-get install apache2
$ sudo apt-get install xrdp
```
　さて、カメラモジュールで数秒に一度写真を撮っていくわけですが、これを毎回SDカードに書き込むとSDカードの寿命が縮まってしまいますので、RAM disk を作成して画像はそこに保存していくことにします。`/etc/fstab` に以下の一行を追加し、再起動します。

```
tmpfs   /var/www/html/image tmpfs   defaults,size=32m   0   0
```
　おおよその準備ができましたのでこの状態で写真を撮るとこんな感じになります。ボカシが多めですが、なんとなくイメージをつかんでいただけると思います。


![変形前イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61220/3414fab4-5512-6dc0-1b71-09a4ccad56b8.jpeg)





　カメラの設置できる場所に制限があるので、画像が斜めになってしまいますね。これでも悪くありませんが、せっかくのRaspberry Pi ですので補正してしまいましょう。補正のために imagemagick を入れます。

```
$ sudo apt-get install imagemagick
```
　早速、imagemagick を使って perspective の修正をします。以下のような感じで修正を行います。（実際に撮影された写真に合わせて数値を変更する必要があります。）また、撮影した日時も画像に埋め込んでしまいましょう。これで今見ている画像の撮影日時を一目で確認することができます。（ntp の設定も必要ですね。）

```
$ sudo convert -matte -virtual-pixel transparent -distort Perspective '695,219 170,0 686,1096 170,1232 1503,1057 1470,1232 1490,283 1470,0' -pointsize 50 -annotate 0x0+10+50 "`date +\"%m/%d %H:%M:%S\"`" -fill yellow /var/www/html/image/image.jpg /var/www/html/image/export_pre.jpg
```
　なお本当は opencv あたりを使ってマーカーを検出してやればフレキシブルなのでしょうが、CPU負荷を高めて消費電力が増えるのもアレですし、カメラは基本的に固定された位置で運用しますので、まずはこのまま運用してみることにします。
　それでは変換後の画像を見てみましょう。


![変形後イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61220/8f233f7b-7a26-5143-986a-376e6b236847.jpeg)



　ちゃんと正面から撮影されているように見えますね！
なお変形はそこそこ重たい処理のようなので、今回はカメラモジュールの設定を 1640 x 1232 の解像度で撮影するようにしてあります。

　動作の確認が取れましたので、これら一連の作業をサービスとして登録してみます。
まずは `/opt/capnconv.sh` という名前でバッチファイルを作成します。最初に初期化のために画像ファイルを削除し、その後写真撮影と変形の処理をループさせる処理を入れます。

```
#!/bin/bash
sudo rm -rf /var/www/html/image/*
while true
do
sudo raspistill -t 1 -w 1640 -h 1232 -o /var/www/html/image/image.jpg
sudo convert -matte -virtual-pixel transparent -distort Perspective '695,219 170,0 686,1096 170,1232 1503,1057 1470,1232 1490,283 1470,0' -pointsize 50 -annotate 0x0+10+50 "`date +\"%m/%d %H:%M:%S\"`" -fill yellow /var/www/html/image/image.jpg /var/www/html/image/export_pre.jpg
sudo mv -f /var/www/html/image/export_pre.jpg /var/www/html/image/export.jpg
sleep 3
done
```

`raspistill`は撮影の命令です。撮影が終わったら perspective の変形を行います。（数字は環境に合わせて書き換えてください。）ここで一旦`export_pre.jpg`というファイル名にして、処理が終わってから`export.jpg`に差し替えます。これはカメラからのデータを書き出している途中に httpd からアクセスしに行くと読み出しに失敗するため、一旦別名で保存してからファイル名を変更するという処置です。外部からは`export.jpg`にアクセスさせます。(html によしなに記述してください。）そしてこれらの処理が終わったら３秒待ってからループします。試してみたところ、Raspberry Pi 3 B でだいたい７秒程度の時間でループするようです。Raspberry Pi Zero の場合はコア数が 1/4 ですので30秒以上かかる感じでした。なお、メインメモリから画像を配信しているため、いったんセッションが繋がってしまえば非常に高速に表示されます。環境に応じて数秒に一度再読み込みをするように`index.html`に設定すると良いでしょう。

さて、このファイルをサービスとして登録するために、`/etc/systemd/system/capnconv.service`というファイルを作成します。

```
[Unit]
Description=Capture and Convert

[Service]
ExecStart = /opt/capnconv.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
```

このサービスを `enable` して自動起動します。

```
$ sudo systemctl enable capnconv
$ sudo systemctl start capnconv
```

　これでプロセスが落ちても再起動してくれるようになりました。

　あとはカメラ等々をちゃんと固定して終了です。

　また、このままではコマンドラインを叩ける人でないと補正の修正ができません。そこで PHP や Javascript などを書いてGUIの設定画面を作ってあげます。弊社ではこんな感じに設定画面を作ってみました。（コードは割愛します。）
![GUI画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61220/4ef87fcf-dd74-89ac-bc4e-3d36ffb5892a.png)


　これでカメラの位置が変わっても、社員がクリックだけで設定変更できるようになりました。

　というわけで、Raspberry Pi を活用し、「補正機能付き定点カメラでコミュニケーションエラーを抑える IoT 活用事例」の紹介でした。