🕺

Visionによる「人間」の検出

2023/12/22に公開

オンデバイスで「人間」を検出する

iOSでは古くはCore Imageの CIDetector で顔の検出ができたし、最近ではVisionフレームワークでディープラーニングベースの顔検出もできる。

しかし顔検出は、顔しか検出できない。画像内における顔領域の大きさが小さかったり、顔が横や後ろを向いているときには画像内に人間がいることを検出できない

そういう場合、YOLOのCore MLモデル(公式でも配布されている)を利用して、personクラスを検出する方法があった。

YOLO で person を検出する際の問題

まず、YOLOによる一般物体検出(Object Detection)はiOSにビルトインされているモデルではないので、Core MLモデルをアプリに同梱する必要がある[2]

この場合、一番小さい YOLOv3Int8LUT.mlmodel を利用しても62.2MBもある。

YOLOv3-Tiny シリーズを使えばモデルサイズはグッと小さくなる(Int8LUT版は8.9MB)が、残念ながら精度も体感できるほどに下がる...

そしてYOLOによる推論処理はそれなりに重い。最新のiPhone 12シリーズでも60 fpsでは処理できないし、端末がアツアツになる。大抵の場合他の画像解析も併用することになるので(僕の場合は音声解析も同時に併用することが多い)、なおさら厳しい。

VNDetectHumanRectanglesRequest

iOS 13から、Visionフレームワークで VNDetectHumanRectanglesRequest というのが使えるようになった [3]

YOLOのpersonクラスを使う代わりになりそうと期待したが、検出範囲が全身ではなく**上半身のみ(顔+胴)**で、完全な代替にはならなかった。

https://twitter.com/shu223/status/1263106775491817477

iOS 15で「全身」の検出が可能に

そんな VNDetectHumanRectanglesRequest が、iOS 15でアップデートされた。revision が VNDetectHumanRectanglesRequestRevision2 となり、全身の検出が可能になった。

(WWDC21「Detect people, faces, and poses using Vision」より)

これで、「人間」を検出するためだけにYOLOモデルを導入する必要はなくなった🎉

upperBodyOnly プロパティ

VNDetectHumanRectanglesRequest に upperBodyOnly プロパティが追加された。

var upperBodyOnly: Bool { get set }

**デフォルトは true**で、この場合、上半身のみの検出となる。

全身を検出したい場合は、falseをセットする。

VNHumanObservation

iOS 13〜14では、VNDetectHumanRectanglesRequest から得られる結果の型は VNDetectedObjectObservation だった。画像内における上半身のバウンディングボックスだけが得られた。

iOS 15からは、VNDetectHumanRectanglesRequest で得られる結果の型が VNHumanObservation という新クラスになった。

var results: [VNHumanObservation]? { get }

VNHumanObservation VNDetectedObjectObservation を継承し、

class VNHumanObservation : VNDetectedObjectObservation

違いとしては、upperBodyOnly プロパティがひとつ追加されているだけ。

var upperBodyOnly: Bool { get }

VNDetectedObjectObservation が持つバウンディングボックスが上半身を表すのか全身を表すのかを示すBool値である。

脚注
  1. 12/22時点で空いていたので書きました。 ↩︎

  2. あとからダウンロードさせる手段もある: Core MLモデルをクラウドにデプロイして配信する ↩︎

  3. 本クラスは、iOS 13.0+, macOS 10.15+のほか、visionOS 1.0+でも使用可能。 ↩︎

Discussion