NVIDIAのJetson Nano 2G 開発者キットでカメラに写った物体の検知をやってみた | そう備忘録

NVIDIAのJetson Nano 2G 開発者キットでカメラに写った物体の検知をやってみた

Hello AI Worldの物体の検知

NVIDIAのJetson Nano 2GB 開発者キットを購入したのでGithubで公開されているHello AI WorldのDeploying Deep Learningの「Locating Objects with DetectNet(DetectNetによる物体の検知)」をやってみた時の記事。

静止画像を読み込んで画像に写っている物体をバウンディングボックス(四角い枠)で囲んで検知して、その物体の名称を推論したり、Jetson NanoにUSB接続したWEBカメラに写っている物体(ペットボトル、フィギュア、etc)のリアルタイムでの推論などを試してみた。

Jetson Nanoによる物体検知

尚、Jetson Nano 2GB 開発者キットのセットアップはこちら、入門コース(Getting Started with AI on Jetson Nano!)をやってみた時の記事はこちら、ディープ・ラーニングによる画像分類についてはこちらの記事を参照して欲しい。

環境

今回の実行環境は以下の通り。

本体

NVIDIA Jetson Nano 2GB 開発者キット

OS

Ubuntu18.04.5 LTS

JetPack SDK

JetPack 4.4.1

カメラ

ロジクール ウェブカメラ C270n

事前準備

セットアップ

Jetson Nano 2GB開発者キットのOSや必要なミドルソフトウェアのセットアップは終了している前提とする。

セットアップについては過去の記事の「Jetson Nano 2GB 開発者キットのセットアップ」を参照して欲しい。

プロジェクトの準備

NVIDIAのHello AIのページの”Running the Docker Container“(Dockerコンテナの実行)をクリックしてページ先の手順に沿ってDockerコンテナの実行を行う。

Hello AI World事前準備

上記リンク先のページの手順に沿って事前準備を行う。

プロジェクトのコピー

git clone --recursive https://github.com/dusty-nv/jetson-inference

Dockerコンテナの実行

cd jetson-inference
docker/run.sh

詳細な手順については「NVIDIAのJetson Nanoで「ディープ・ラーニングによる画像分類」をやってみた」の事前準備の章を参照して欲しい。

必要に応じてデフォルト以外のモデルをダウンロードすることも出来る。

物体検出

使用するモデル

モデルは91-class SSD-Mobilenet-v2 model trained on the MS COCO datasetを使用した。

以下の特徴がある。

  • Microsoftが提供しているCOCOデータセット上で学習させている
  • COCOはCommon Objects in Contextの略で日常的な物を学習させている
  • (今回のモデルは)91種類のクラス分類が可能
  • 物体の検知のアルゴリズムにSSD(Single Shot MultiBox Detector)を使用している
  • モバイル端末でも使用できる軽量なCNN(Convolutional Neural Network)のMobilenet Version2を使用している

学習済みの91種類のモノはこちらの一覧で確認して欲しい。

静止画の物体検出

まずは静止画の物体検出を試みる。

LXTerminalから該当ディレクトリに移動して物体検出プログラム(detectnet.py)を以下のコマンドで実行する。

尚、初回の実行はネットワークの最適化などで若干時間がかかる。

cd build/aarch64/bin/
./detectnet.py --network=ssd-mobilenet-v2 images/peds_0.jpg images/test/peds_out.jpg

detectnet.py

物体検知用プログラム(後述

画像、映像を入力として学習済みの物体を検知してバウンディングボックス(四角い枠)で囲み、名称を推論する。

–network

使用するネットワーク(ssd-mobilenet-v2)を指定した。

指定できるネットワークは以下の通り。

ssd-mobilenet-v1

COCO MobilenetのVersion1

ssd-mobilenet-v2

COCO MobilenetのVersion2

ssd-inception-v2

SSD-Inception-v2

coco-dog

dogs(犬)

coco-bottle

bottles(ボトル)

coco-chair

chairs(椅子)

coco-airplane

airplanes(飛行機)

pednet

pedestrians(歩行者)

multiped

pedestrians, luggage(歩行者、荷物)

facenet

faces(顔)

入力画像

入力画像(images/peds_0.jpg)の指定。

横断歩道を数人の歩行者が横切っている写真を使用した。

出力画像

物体検知後の写真の出力先(images/test/peds_out.jpg)

Dockerコンテナ実行後もファイルが残るディレクトリ(images/test/)を指定している。

4人の歩行者がperson(人)として検知されて、緑色の枠(バウンディングボックス)で囲まれている。

また予測スコアが表示されているが一番左の女性が69.9(%)と若干低い事も分かる。

プログラム中でデフォルトで50%以上のしきい値の物体のみを検知するようにしている。

pednetでの実行結果

同様の写真に対してpednet(歩行者)のネットワークで試した時の出力結果。

pednet(歩行者)での検出結果

左の2人が1つの大きなバウンディングボックスで囲まれて、156.4%(100%以上)のスコアが検知されている。

また真ん中の男性も100%以上のスコアを示している。

facenetでの実行結果

同様の写真に対してfacenet(顔)のネットワークで試した時の出力結果。

facenet(顔)での検出結果

サングラスを掛けていたり、若干うつむき気味であっても顔のみが正しく検知できている。

また一番右の後ろ向きの男性は顔が写っていないので検知されていない。

人と犬の写真

人と犬が写った写真の ssd-mobilenet-v2 での検出結果。

人と犬がぞれそれ検出されている。

coco-dogでの実行結果

上記と同じ写真の coco-dog ネットワークでの検出結果。

人は検出されずに犬だけが検知されている。

使用するネットワークを用途によって使い分けることにより特定のモノのみを検出することが出来る。

プログラムソース

detectnet.py のソースコードは以下の通り。

上部にNVIDIAの著作権(制限無しで使用可能、コピー、変更、マージ、公開、配布、サブライセンス・・・)が記述されている。

またコード中に日本語でコメントを追記した。

#!/usr/bin/python3
#
# Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#

import jetson.inference
import jetson.utils

import argparse
import sys

# parse the command line
parser = argparse.ArgumentParser(description="Locate objects in a live camera stream using an object detection DNN.", 
                                 formatter_class=argparse.RawTextHelpFormatter, epilog=jetson.inference.detectNet.Usage() +
                                 jetson.utils.videoSource.Usage() + jetson.utils.videoOutput.Usage() + jetson.utils.logUsage())

parser.add_argument("input_URI", type=str, default="", nargs='?', help="URI of the input stream") # 入力
parser.add_argument("output_URI", type=str, default="", nargs='?', help="URI of the output stream") # 出力
parser.add_argument("--network", type=str, default="ssd-mobilenet-v2", help="pre-trained model to load (see below for options)") # 使用ネットワーク(デフォルトはssd-mobilenet-v2)
parser.add_argument("--overlay", type=str, default="box,labels,conf", help="detection overlay flags (e.g. --overlay=box,labels,conf)\nvalid combinations are:  'box', 'labels', 'conf', 'none'") # オーバーレイ表示
parser.add_argument("--threshold", type=float, default=0.5, help="minimum detection threshold to use") # しきい値 50%以上を検出対象

is_headless = ["--headless"] if sys.argv[0].find('console.py') != -1 else [""]

try:
	opt = parser.parse_known_args()[0] # パラメーターのチェック
except:
	print("")
	parser.print_help()
	sys.exit(0)

# load the object detection network
net = jetson.inference.detectNet(opt.network, sys.argv, opt.threshold) # detectNetの起動

# create video sources & outputs
input = jetson.utils.videoSource(opt.input_URI, argv=sys.argv) # 入力 videoSourceは画像、映像両方に対応
output = jetson.utils.videoOutput(opt.output_URI, argv=sys.argv+is_headless) # 出力

# process frames until the user exits
while True:
	# capture the next image
	img = input.Capture() # キャプチャーして画像をimgに保存

	# detect objects in the image (with overlay)
	detections = net.Detect(img, overlay=opt.overlay) # 画像をベースにモノを検出、検出部をオーバーレイ表示

	# print the detections
	print("detected {:d} objects in image".format(len(detections)))

	for detection in detections:
		print(detection)

	# render the image
	output.Render(img) # 画像・映像を出力(videoOutputは両方に対応している)

	# update the title bar
	output.SetStatus("{:s} | Network {:.0f} FPS".format(opt.network, net.GetNetworkFPS()))

	# print out performance info
	net.PrintProfilerTimes()

	# exit on input/output EOS
	if not input.IsStreaming() or not output.IsStreaming(): # ストリーミング中で無ければ終了
		break

補足説明

入力、出力で使用している jetson のユーティリティの videoSource(入力) と videoOutput(出力) は画像、映像の両方に対応している。

videoSource

指定例

  • /path/xxx.jpg:画像
  • /path/xxx*.jpg:ワイルドカードで複数の画像ファイルを指定
  • /path/xxx.mp4:映像ファイル
  • csi://0:csiコネクタに接続したカメラ
  • /dev/video0:USB接続したカメラ

videoOutput

指定例

  • /path/xxx.jpg:画像に保存
  • /path/xxx%.jpg:複数の画像ファイルに保存
  • /path/xxx.mp4:映像ファイルに保存
  • 未指定:デスクトップ(GUI)の際はWindowに表示される

動画の物体検出

続いてUSB接続したWEBカメラに写った物体をリアルタイムで物体検知してみる。

Jetson NanoにUSB接続したWEBカメラを取り付けて物体検知をやってみる

Jetsonはデスクトップ(GUI)表示している状態でLXTerminalから以下のコマンドで先程を同じプログラムを実行する。

ネットワークは指定をしないとデフォルトのCOCO MobilenetのVersion2が使用される。

./detectnet.py /dev/video0

物体検知の様子は以下の動画で確認して欲しい。

デジタル時計

デジタル時計については若干認識しない怪しい時もあったが正しく認識された。

cocoではこのタイプのデジタル時計の学習量が足りないのかも知れない。

デジタル時計

レゴのフィギュア(女性)

レゴのフィギュア(女性)については常にperson(人)と認識された。

尚、もっとデフォルメされたレゴのフィギュアもpersonと認識されたので人は比較的認識しやすい物体(Object)のようだ。

レゴのフィギュア

ニホンカモシカ

海洋堂のニホンカモシカは距離が離れるとperson(人)、近づくとdog(犬)と認識された。

また時々 horse(馬)と認識された時もあった。

また台座の上の雪が積もった足場の石の部分が boat(ボート)と判定されることもあった。

そもそもニホンカモシカは coco では学習していないので正しく判定されないのはある意味当然の結果だ。

ニホンカモシカは犬と判定された

ペットボトル

ペットボトルはbottle(ボトル)と判定されたが中心部が何故かclock(時計)と判定されることもあった。

ペットボトルはbottleと判定された

終わりに

デフォルトで用意された coco mobileモデルで、ある程度の精度が出ることが分かった。

利用目的にも寄るが監視カメラでの物体検知(個人利用)程度であれば十分な精度であると感じた。

より精度を上げたり新しい物体を学習させる為には別途転移学習が必要になる。

転移学習については別記事としたい。

以上で今回の記事は終了とする。

最後に

この記事が何処かで誰かの役に立つことを願っている。

尚、当記事中の商品へのリンクはAmazonアソシエイトへのリンクが含まれています。Amazonのアソシエイトとして、当メディアは適格販売により収入を得ていますのでご了承ください。

souichirou

やった事を忘れない為の備忘録 同じような事をやりたい人の参考になればと思ってブログにしてます。 主にレゴ、AWS(Amazon Web Services)、WordPress、Deep Learning、RaspberryPiに関するブログを書いています。 仕事では工場に協働ロボットの導入や中小企業へのAI/IoT導入のアドバイザーをやっています。 2019年7月にJDLA(一般社団法人 日本デイープラーニング協会)Deep Learning for GENERALに合格しました。 質問は記事一番下にあるコメントかメニュー上部の問い合わせからお願いします。

おすすめ

3件のフィードバック

  1. ggg より:

    このサイトを参考にしているものです
    カメラを持った男性と犬の写ったいる写真のもと画像を貼っていただきたいです。

  1. 2021年5月6日

    […] NVIDIAのJetson Nanoで物体の検知をやってみた/そう備忘録 […]

質問やコメントや励ましの言葉などを残す

名前、メール、サイト欄は任意です。
またメールアドレスは公開されません。