物体検出監視カメラ

# はじめに

今回、自作で物体検出のできる監視カメラを作成しました。本記事では、開発にあたって設定した要件をまとめてご紹介します。

# 1.テーマ
「自身で監視カメラを開発し、運用までを行う」という目標のもと開発した、物体検出で人間のみを検知し、discord(メッセージアプリ)に検知時の画像を送信するアプリケーションです。

# 2.課題の定義
## 解決すべき課題
実家に空き巣が入り、急遽、市販の監視カメラを設置しました。しかし、運用するにあたって、いくつかの課題を発見するに至りました。
#### 2.1 可用性の問題
- 上手く物体検出しないことがある
- デバイスに送信される画像がコマ送りになっており、前後の映像が取得できない
- 画質が悪く、正確な情報を得られない
#### 2.2 ユーザビリティの問題
- 専用アプリが使いにくく、独自の設定をユーザ側が手動で行う必要がある
- アプリの通知が届かない時があり、検知した場合に即座の対応が難しい


## 3.解決方法
フルHDのwebカメラを使用し、Discordを介して画像を送受信することで、画質の問題・通知の不安定性を解消。また、Discordのチャネルを参照するだけで、前後の画像を取得できるようにすることで、ユーザビリティの改善を図る。

## 4.システムアーキテクチャ

### 4.1 システム構成図
![スクリーンショット 2024-08-13 191252.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860038/52f72174-f2c9-8d29-122f-9402428af944.png)

### 4.2 ハードウェア構成
- クライアント側：Raspberry Pi Zero 2 W
- サーバー側：MacBook Air 2020

### 4.3 ソフトウェア構成
- クライアントサイド（Python）
   - Githubレポジトリ https://github.com/shima20913/human_detection_camera_client
   - OS: Ubuntu 22.04.4 LTS (64-bit)
   - Python バージョン 3.10.5
   - 主要ライブラリ：Pygame
-  サーバーサイド（Go）
   -Githubレポジトリ https://github.com/shima20913/human_detection_camera
   - OS: Ubuntu 22.04.4 LTS (64-bit)
   - Go バージョン: 1.22.5
   - 外部サービス連携：DeepDetect API（Docker上で動作）
-  送信先：Discord



### 4.4 採用技術の背景
- #### クライアントサイドのpython選定理由
  - カメラの運用についての技術記事の多くが、pythonで説明されていたこと
  - pythonがRaspberry Piとの高い親和性をもつこと(公式推奨)
  - 画像処理関係のライブラリが豊富に存在すること
- #### サーバーサイドのGo選定理由
  - サーバーサイド言語として流行を見せている言語のため
  - コンパイル言語として、高速な処理を実現できるため
-  #### Pygameの採用理由
   - 当初はGoCVの使用を予定していたが、Raspberry Pi Zero 2 Wのマシンスペック不足により動作しなかったため、軽量で動作が安定しているPygameを代替として採用した

- #### DeepDetectの採用理由
  - 事前に学習されたカスタムモデルが公開されていたため

- #### Dockerの選定理由
  - DeepDetect APIをコンテナ化することで、システムの他の部分に影響を与えることなく、独立して管理・更新することができるため

### 4.5 バージョン管理
- Git/GitHub
# 5.機能要件
### 5.1 クライアント側（Python）
- カメラからの画像キャプチャ
- 1秒ごとに画像を撮影する
- 撮影した画像をサーバーへ送信する
- 送信後の画像ファイル削除

### 5.2 サーバー側（Go）
- 画像のアップロード受付
- DeepDetect APIとの連携
- 人物検出時にDiscordへ通知
- 画像キューの管理（最大5枚）

### 5.3 DeepDetect（Docker）
- 物体検出モデルの提供
- 画像分析

## 6. 詳細要件

### 6.1 クライアント側
- Pygameを使用してカメラ制御
- 環境変数からサーバーURLと撮影間隔を設定可能

### 6.2 サーバー側
- 画像受信
- DeepDetectを使用した物体検出
- 人物または顔が検出された場合のみDiscord通知
- 検出された画像の前後の画像も含めてDiscordに送信
- 画像ファイルの一時保存と自動削除
- Byobuを使用してバックグラウンドで継続稼働

## 7. 非機能要件
### 7.1 パフォーマンス
- 継続的に監視を行うため、1秒に1枚のペースで画像をキャプチャする
### 7.2 可用性
- サーバープロセスが予期せず終了した場合、自動的に再起動するよう設定
- クライアント側・サーバー側両方で画像を一時ファイルとして保存し、処理の確実性を高めている
- .env ファイルを使用して環境変数を管理することで、システムの動作をソースコードを変更せずに調整できるようにする
- クライアント側は自動起動スクリプトによる継続的な監視を実現
- サーバー側は、Byobuによるバックグラウンド継続稼働
### 7.3 セキュリティ
- .envファイルを用い、サーバーURLやdiscord_webhookURL等の機密情報を管理することで、漏洩リスクを低減
- 一時ファイルの不正アクセスを防ぐため、アップロードされた画像を処理後に削除
- 画像アップロード時にPOSTリクエストのみを許可し余分なアクセスリソースを排除
### 7.4 保守性
- システムの稼働において重要な操作と、そのエラーを標準出力する
### 7.5 互換性
- 主要osで動作する機能を使用

## 8.動作テスト

人間を検出すると、"Person Detected"と表示され、Discordへ画像が送信される。
![mosaic_20240813213452.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860038/985cba80-6edb-7b33-a67d-775a9c9a22bc.png)


大成功です。一番上が検知時、中央が検知前、最下部が検知後。
![face.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860038/0b8b5e58-33ac-6596-42e7-27d3e556532a.png)

## 9.今後の課題・目標
- Webインターフェースを用意し、検知結果やシステムの状態をリアルタイムで確認・管理できるダッシュボードを作成する。(<font color="red">**実装したため、別記事にて公開しました。https://qiita.com/shima20913/items/6bab5ac1e75574e4dfb3**</font>)
- スマートフォンやタブレットからもシステムの状態を監視できるよう、対応のフロントエンド開発を行っていきたい
- 今回は学習済みモデルを使用したが、自身でディープラーニングさせたモデルを作成し、実用化させたい
- Raspberry Pi Zero 2 Wが正常に動作しているか、エラーハンドリングだけでなく、アラートなどの音声で聴覚的に判断できる仕様を追加したい