物体検出プログラム(SSD)で小さい物体を検出する方法を考えたので、ひなまつりチロルチョコで検証してみた話

2021年6月19日

image_hinamaturi
今回の検証アイテム(おひなさまチロルチョコ)

SSDとは

SSD(Single Shot MultiBox Detector)は2016年に提案された物体検出モデル(ディープラーニングモデル)です。

特徴は、画像に8732個のデフォルトボックスを敷き詰め、デフォルトボックスごとに位置推定クラス分類を行うことです。

この位置推定とクラス分類を1つのCNNで実行することができるため、従来の物体検出モデル(Fast R-CNN)より計算量が少なく、リアルタイム処理しやすくなりました。

しかし、このSSDモデルも畳み込みニューラルネットワーク(CNN)を用いているため、ある弱点があります。

CNNの弱点とは

CNNとは、簡単に言うと5×5ピクセルや7×7ピクセルのフィルタ(カーネル)サイズごとに特徴を抽出して、その特徴だけを残したマップをたくさん作る作業のようなものです。

例えば物体認識(クラス分類)によく使われるVGG16もCNNを使った学習モデルの一つです。

このモデルは比較的畳み込み回数の少ないモデルですが、物体が小さいと認識しない又は認識率が非常に低くなります。

これは、畳み込みを繰り返すなかで最終的な特徴マップまでその特徴が残らなかったということを示しています。

ちなみに、これを確認する方法として、例えばCNNの一連の畳み込み層によって入力画像がどのように変換されるのかを可視化してみれば分かります。この話はまた別の機会に書きたいと思います。

実は、SSDモデルにもベースネットワークとしてVGG16が使用されています。

代表的なSSDモデルとしてはSSD300(300×300ピクセルの画像で学習・推論)とSSD512(512×512ピクセルの画像で学習・推論)があります。

ここではSSD300について書きます。

メリットは学習時の計算量が小さいことです。

計算量は計算負荷(パソコンのスペック)や計算時間(作業効率)に影響します。

一般的には計算負荷が小さく作業効率が高い方が実用的なため、今回はSSD300で検証を行いました。

SSD300について

SSD300(300×300ピクセルの画像で学習・推論)では、VGG16をベースネットワークとしExtra Feature Layersの追加ネットワークを結合した構造になっています。

SSDネットワーク(https://arxiv.org/pdf/1512.02325.pdf :より借用)

SSD300に画像を入力すると300×300ピクセルにリサイズ(縮小)され、VGG16ベースネットワークから追加ネットワークの順に順伝播計算して行きます。

入力画像がどんなに大きくても、SSD300のネットワークに入力すると300×300ピクセルに縮小されてしまいます。これは、300×300ピクセルの画像であらかじめ学習した学習モデルを使って推論が実行されるためです。

SSD300ではネットワークの浅い層(左側のブロック)では小さな物体を、深い層(右側のブロック)では大きな物体を検出するような構成になっています。

浅い層は畳み込みが少ないため、特徴抽出が不十分で認識精度が低くなる(物体の特徴が十分にとらえられていない)傾向があります。

一方、深い層では畳み込みが多いため、特徴抽出が十分で認識精度は高くなる(物体の特徴を十分にとらえている)傾向があります。

層の深さ認識精度
浅い低い
深い高い

これらの予備知識を踏まえた上で次の画像をみてください。

物体が大きく映っている場合の検出結果

image_hinamaturi

今回はおひなさまチロルチョコをテーブルの上に置いて検出しています。

おひなさまチロルチョコを認識してバインティングボックスという四角い枠が表示されました。

物体が小さく映っている場合の検出結果

矢印の箇所にひなまつりチロルチョコが置いてあります。

お内裏様、お雛様、三人官女の合計5個です。

SSD300で推論させた結果が以下です。

写真1 矢印の場所におひなさまチロルチョコがあります
写真2 拡大した様子

だれも検出できていません。

検出させたい物体があまりにも小さいためです。

小さい物体を検出させる方法

以下の3ステップで推論させます。

  1. 入力画像を分割
  2. 分割画像ごとに推論
  3. 推論後に画像結合

上記で述べた通り、画像がどんなに大きくてもSSD300に入力すると内部で300×300ピクセルにリサイズしてしまいます。

このため、検出させたい物体の大きさも相対的に小さくなってしまい、より検出されにくくなってしまいます。

これを避けるために、SSD300内部で推論計算に入る前に入力画像を300×300ピクセルに近いサイズに分割してリスト化しておきます。

なお、300×300ピクセルに近いサイズでよい理由は、結局SSD300の内部でリサイズしてしまうからです。

一般的に、リサイズすると画像のディテール情報が欠落します。

このため、若干大きめのサイズで分割しなるべくディテール情報の欠落を小さくすることがおすすめです。(例:400×400)

リスト化した画像に対して、1枚づつ推論を行い結果をフォルダに保存しておきます。

すべての画像の推論が終わったところで、フォルダ内に保存した画像を読み出して結合します。

本方法を使った場合の検出結果

image_ohinasama
写真3 矢印の場所におひなさまチロルチョコがあります
image_hinamaturi_expansion
写真4 拡大した様子

みんな検出できています。すばらしい!

なお、写真1や写真3は一眼レフカメラ(CanonのEOS 5D Mark Ⅳ)で撮影後、4480×4480ピクセルにトリミングして入力画像として用いています。

SSD300内部で推論計算に入る前に、入力画像を448×448ピクセルの画像10枚に分割し、300×300ピクセルにリサイズして推論しています。

解像度の高いカメラなら更に小さな物体も検出できると思います。

応用範囲

本方法を使えば、かなり小さな物体でも検出できると思います。あとはカメラの解像度次第です。

以下のようなタスクには非常に有効かもしれません。

  • 工業関係では微小なキズ、異物、クラック、汚れ等の検出
  • 医療関係では小さな腫瘍等の検出
  • 農業関係では作物の病気による黒点、キズ、汚れ等の検出

参考にした書籍