はじめに
こんにちは。
先週は他業務を優先していたため記事を公開できませんでしたが今週からまた記事を更新していこうと思います。
ここ数週間はAIエージェント開発をするための技術を記事にまとめてきましたが、今週からは除雪DXに向けた取り組みを記事にしていく予定ですので、ご覧いただけますと幸いです。
今回やること
除雪作業の自動化が進んだとしても、安全対策は依然として不可欠です。
万が一、人を巻き込んでしまえば重大な事故につながるため、除雪車には人を検知するレーダーなどの安全装置が搭載されています。
しかし、レーダーの検知範囲外に歩行者がいる場合には、作業者自身の目視確認が必要です。
ところが、雪や障害物によって視界が遮られる状況では、たとえ注意していても歩行者の存在を認識できないことが想定されます。
では、「人の目では認識できない」状況に、どう対処すれば良いのでしょうか?
今回はその課題への一つのアプローチとして、Webカメラの映像をもとに機械学習モデルで人を検出し、視界不良時でも作業者に警告を表示するシステムを試作してみました。
本来であれば赤外線カメラやサーマルカメラのようなセンサーを活用するのが理想的ですが、現時点では手元にないため、まずは一般的なWebカメラで試しています。
さらに今回は、AI開発支援ツールの Devin を活用して実装してみました。
類似研究
視界不良時において、「どこに何があるか」を識別する手法を調査していたところ、以下のリンク先にある興味深い研究事例を見つけました。
この研究では、雨や霧といった視界を妨げる要素を画像から除去し、元の景観を復元することを目的としています。
手法としては、アンサンブル学習(複数の機械学習モデルを組み合わせて精度を高める技術)が用いられており、たとえばカメラレンズに付着した雨粒なども除去できるようです。
効果的な技術ですが、アンサンブル学習は計算コストや開発負荷が高くなる傾向があるため、私自身はまだ扱ったことがありません。とはいえ、ページ内で紹介されているような「視界のクリア化」は、今回の取り組みにとっても大きなヒントになりそうです。
今回は、より手軽に試せる方法として、Webカメラと人検出モデルを組み合わせたシンプルなアプローチを選びました。

機械学習
データセット
今回の試作では、MS COCOデータセットを使用しました。
このデータセットは、多数のカテゴリ(人物を含む)を網羅した一般的な物体認識用のデータセットであり、自前で専用のデータセットを構築しなくても物体検出タスクに活用できる点が大きな利点です。
しかし、今回の目的は、豪雪地帯の夜間など視界が極端に悪い状況下で、作業者の目では認識しづらい人物を検出することです。
MS COCOデータセットだけでは、そうした極端な条件を満たす画像が十分とは言えなかったため、追加で適切な画像データを収集・準備しました。
以下のような夜間画像では、人の目では認識しづらい人物も、画像処理技術を活用することで、その輪郭や形状から人物であると推定できるケースがあります。

さらに、下図のような降雪時の視界不良な環境下においても、人物を検出できることを目指します。

アノテーション
ramble内でも度々話題にしている通り、アノテーションは物体検出タスクにおいて非常に重要な工程です。
アノテーションとは、画像内の対象物を特定のクラス(カテゴリ)に分類し、その位置情報を明示する作業を指します。
たとえば、下図のようにオブジェクトごとに四角形(バウンディングボックス)で囲い、それにクラスラベルを付与することで、画像中の対象を「人物」「車両」「標識」などに分類することが可能になります。
このようなアノテーションによって、カテゴリごとの特徴量を学習させることができ、モデルが対象物を正確に識別できるようになります。

学習
学習はいつも通りpytorchで実装し、機械学習モデルにはFCOSを使用しました。
今回は人物が映った画像に対して、頭部、上半身、全身の3クラスを定義することで、何らかの物体に遮られたとしても体のどこかが検出されるようなデータセットを作成しました。
学習時のf1スコアを確認した結果、10エポック以降あまり伸びなかったため、この辺りのモデルを使用します。

Devinでリアルタイムな人検出システムの実装
WEBカメラ
WEBカメラを使う理由として、実際に利用する場合、画像として得るよりもリアルタイムに撮影することが好ましいと考えたため、WEBカメラを使用します。
冒頭でも少し触れましたが、冬季の夜間における人検出を想定するなら、本来は赤外線カメラやサーマルカメラのような特殊なカメラの方が適しています。
しかし、現時点ではそれらを使用できる環境が整っていないため、今回は入手が容易で汎用性の高いWebカメラを用いて、リアルタイムな人検出の仕組みを構築しました。
カメラの起動にはOpenCVのcv2.VideoCapture()を使用することでデバイスのカメラや外付けのWEBカメラを自由に使うことができます。
工夫
通常のWebカメラでは、夜間のような暗い環境でどこまで映像を捉えられるのかが不明だったため、いくつかの工夫を試みました。
今回は、Webカメラに対してRGBそれぞれのフィルタ処理を適用することで、真っ暗な環境下でも人物の検出が可能になるのではないかと考えました。
特に、赤(R)や緑(G)のチャンネルに着目することで、わずかな光源や反射の違いから人物の輪郭を強調できる可能性があります。
このように、RGBフィルタを活用することで、暗闇の中でもおおよそ半径10メートル程度の範囲で人物を認識できることが期待されます。
while True:
ret, frame = cap.read()
b, g, r = cv2.split(frame)
# R, G, B フィルタ画像を作成(他チャンネルをゼロにする)
red_img = cv2.merge([np.zeros_like(b), np.zeros_like(g), r])
green_img = cv2.merge([np.zeros_like(b), g, np.zeros_like(r)])
blue_img = cv2.merge([b, np.zeros_like(g), np.zeros_like(r)])
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
Devinにお願い
ここまでで必要なものは全て揃ったので、ここからはDevinの登場です。
Devinだけでなく、他のAIエージェントを使用する上でプロンプトの書き方は非常に重要です。
Devinではどのようなプロンプトを描くのが良いのか今後も追求していきますが、現状では以下のように処理手順を明確にしてまとめることが齟齬がなくスムーズに進んでいるような実感がありました。

完成
フィルタをかけてみましたが、あまりうまくいっていないですね…
ただカメラからかなり離れても検出はされていたので、検出精度は現状ではまあまあ良い結果と言えるでしょう。

おわりに
今回は、人検出モデルを活用して、Webカメラ映像からリアルタイムに人物を検出するアプローチに取り組んでみました。
WEBカメラにRGBのフィルタ処理をすることで暗い環境でも人物オブジェクトの輪郭を強調できるように工夫していたつもりでしたが、ソースコードを見直してみたところ、フィルタが適用されていたのはGUI上の表示のみ、モデルに入力されるリアルタイムな映像自体には反映されていませんでした。
これを修正するにはカメラの構成そのものを変更する必要があるため、代案としてリアルタイム映像をから画像として取得し、RGBのフィルタ処理をする方法を検討していきます。
今回作成したソースコードは下記のgithubのリンクから使用することができます。