本ページは i-PRO株式会社 の有志メンバーにより記載されたものです。
本ページの情報は ライセンス に記載の条件で提供されます。
MobileNet-SSD は、高速に物体物体検知を行うAIモデルの一つです。高い認識性能と共に GPU を搭載しない組み込み機器でも動作する軽量なモデルであることに特徴があります。
本ページでは、MobileNet-SSD を使ってカメラ映像を画像処理する方法について記載します。
MobileNetSSD は V1, V2, V3 まで発表されていますので、これらを1つずつ動作させてみたいと思います。i-PRO カメラと接続して使用する手順についても具体的に紹介していきます。
こちら、私のノートPCで CPU 動作させた例です。GPU無しの動作環境ですがこれぐらいでリアルタイム動作できています。
"i-PRO mini" 紹介:
"モジュールカメラ" 紹介:
カメラ初期設定についてはカメラ毎の取扱説明書をご確認ください。
カメラのIPアドレスを確認・設定できる下記ツールを事前に入手しておくと便利です。
Python を事前にインストール済みであることを前提に記載します。
私の評価環境は以下の通りです。
言語 : | Python, | 3.10.4 |
OS : | Windows 11 home, | 21H2 |
Windows 10 pro, | 21H2 | |
こちら「PyTorch をインストールする - 1-1. CPU」の記事を参考にインストールを行います。
Windows 環境で多くの人が試せるようにしたいので、本ページでは「Compute Platform」を「CPU」としてインストールしている前提で説明を記載します。NVIDIA の GPU など特定のハードウェアを必要としません。
opencv を使用するので、下記コマンドによりインストールします。
pip3 install opencv-python
2017年に MobileNet v1 が発表されました。(MobileNet V1 の原著論文)
分類・物体検出・セマンティックセグメンテーションを含む画像認識を、モバイル端末などの限られたリソース下で高精度で判別するモデルを作成することを目的として作成しています。
MobileNetV1 は下記2つの技術により高速化を行っています。
MobileNet(V1) のアーキテクチャ構造です。
MobileNet(V1) の物体検出性能を、COCOデータセット上で評価・比較した結果です。論文からの引用です。
引用元: MobileNet V1 の原著論文
mAP | 認識性能の平均値(mean Average Precision) |
Mult-Adds | 積和演算の回数 |
Parameters | 重みの数 |
上記結果から、MobileNet(V1) は、認識性能(mAP)を大きく低下することなく計算量(Mult-Adds)を劇的に削減できていることを読み取れます。
MobileNetV1-SSD を PyTorch の環境で動かしてみます。
pytorch-ssd というこの内容そのままのものが GitHub で公開されていました。これを取得して動作させてみます。
ちなみに pytorch-ssd のライセンスは "MIT License" です。
言語 : | Python, | 3.10.4 |
PyTorch, | 1.11.0+cpu | |
OS : | Windows 11 home, | 21H2 |
Windows 10 pro, | 21H2 | |
1. pytorch-ssd から git clone してソースコード一式を入手します。
任意のフォルダで端末(コマンドプロンプト等)を起動して下記コマンドをインプットします。
(git を既にインストール済みとして記載します。)
$ git clone https://github.com/qfgaohao/pytorch-ssd.git
2. "git clone" したフォルダへ移動します。
$ cd pytorch-ssd
3. README.md 中の "Run the live MobilenetV1 SSD demo" に記載の内容に従って下記を実行します。
下記 Google Drive を開いて、"mobilenet-v1-ssd-mp-0_675.pth" および "voc-model-labels.txt" の2つのファイルを取得して models フォルダに保存します。
https://drive.google.com/drive/folders/1pKn-RifvJGWiOx0ZCRLtCXM5GT5lAluu
NOTE
2023/3/11 の pytorch-ssd 更新によりモデルファイルの取得方法が変更になりました。
4. 下記コマンドを実行することで推論を実行します。
$ python run_ssd_live_demo.py mb1-ssd models/mobilenet-v1-ssd-mp-0_675.pth models/voc-model-labels.txt
学習済みモデルは VOC dataset を使って学習しているので、このプログラムは下記 20クラス を検知します。
1: aeroplane 2: bicycle 3: bird 4: boat 5: bottle 6: bus 7: car 8: cat 9: chair 10: cow 11: diningtable 12: dog 13: horse 14: motorbike 15: person 16: pottedplant 17: sheep 18: sofa 19: train 20: tvmonitor
5. 上記手順でプログラム("python run_ssd_live_demo.py ・・・" のところ)を実行したところ、私の環境では下図のようなエラーを表示して正常に動作しませんでした。
どうやら、box[0], box[1], box[2], box[3]
が浮動小数点なのですがここの引数は整数(int)である必要がある、ということがエラーの理由のようです。
エラーとなった 76行目と、同様に
79行目の2カ所を int 型へ変換するように修正します。下図だと4行目、7行目の色付きの場所へ int() を追加しました。
これでエラーを解決してプログラムを実行できるようになりました。
for i in range(boxes.size(0)): box = boxes[i, :] label = f"{class_names[labels[i]]}: {probs[i]:.2f}" cv2.rectangle(orig_image, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), (255, 255, 0), 4) cv2.putText(orig_image, label, (int(box[0])+20, int(box[1])+40), cv2.FONT_HERSHEY_SIMPLEX, 1, # font scale (255, 0, 255), 2) # line type
別サイトの記事記載[9] によると、OpenCVバージョンアップに伴う影響だそうです。元々はこのようなエラーは出なかったのでしょう。
修正を Pull Request #178 しておきましたが、ポスト後に確認したら私を含めて3件の同件修正が Pull Request されていました。こちらのリポジトリはメンテを終了しているかもしれません。
(2022-08-03 追記)
私から出した Pull Request (#178) が先ほどマージされました。
このためマージ後のソースを取得(git clone)した方はこちら 5 に記載の修正は不要です。
Bug fix. by kinoshita-hidetoshi · Pull Request #178 · qfgaohao/pytorch-ssd · GitHub
6. 修正したプログラムを動かした様子を以下に示します。
カメラはPC内蔵のカメラです。PyTorch は前述の通り CPU 版ですがかなり快適に動作できています。
[動画] プログラムを動作させた様子(PC 内蔵カメラ)
NOTE
プログラム "run_ssd_live_demo.py" 中で PC内蔵カメラ からのキャプチャーを行っている部分は下記の箇所です。
cap = cv2.VideoCapture(0) # capture from camera
MobileNetV1-SSD を PyTorch の環境で動かしてみます。
本章では i-PRO カメラとPCを LAN 接続してリアルタイムで物体検知してみます。前章と同様に pytorch-ssd を使って行います。
言語 : | Python, | 3.10.4 |
PyTorch, | 1.11.0+cpu | |
OS : | Windows 11 home, | 21H2 |
Windows 10 pro, | 21H2 | |
1. pytorch-ssd から git clone してソースコード一式を入手します。(前章と同じです。実施済みなら不要です。)
任意のフォルダで端末(コマンドプロンプト等)を起動して下記コマンドをインプットします。
$ git clone https://github.com/qfgaohao/pytorch-ssd.git
2. "git clone" したフォルダへ移動します。
$ cd pytorch-ssd
3. README.md 中の "Run the live MobilenetV1 SSD demo" に記載の内容に従って下記を実行します。(前章と同じです。実施済みなら不要です。)
下記 Google Drive を開いて、"mobilenet-v1-ssd-mp-0_675.pth" および "voc-model-labels.txt" の2つのファイルを取得して models フォルダに保存します。
https://drive.google.com/drive/folders/1pKn-RifvJGWiOx0ZCRLtCXM5GT5lAluu
NOTE
2023/3/11 の pytorch-ssd 更新によりモデルファイルの取得方法が変更になりました。
4. 下記コマンドを入力してプログラムを起動します。ここでは4番目の引数として RTSP 表記で i-PRO カメラの接続を記載します。
{user-id}, {password}, {ip-address} の部分をご自身が使われる i-PRO カメラの設定に合わせて修正して実行してください。
その他 RTSP に関しては記事「RTSP で画像を取得する」を参照ください。
$ python run_ssd_live_demo.py mb1-ssd models/mobilenet-v1-ssd-mp-0_675.pth models/voc-model-labels.txt rtsp://{user-id}:{password}@{ip-address}/MediaInput/stream_1
(例) python run_ssd_live_demo.py mb1-ssd models/mobilenet-v1-ssd-mp-0_675.pth models/voc-model-labels.txt rtsp://admin:Admin12345@192.168.0.10/MediaInput/stream_1
5. プログラムを動かした様子を以下に示します。
PyTorch は前述の通り CPU 版ですがかなり快適に動作できています。
i-PRO カメラの設定を 10fps にしています。私のノートPC環境では 30fps 動作させると映像が少しずつ遅延していきました。AI処理なしに映像表示させると 30fps 表示できているので、AI処理に伴うCPU負荷に原因するものと分析します。GPU無しの環境、CPU 版での動作で Full-HD 画像を 10fps でAI処理できているのですから、私個人の見解ですが、 MobileNet は十分に軽量で高性能な AI だと考えます。
[動画] プログラムを動作させた様子 1(i-PRO カメラ)
[動画] プログラムを動作させた様子 2 - 「人 商業 店 - Free video on Pixabay」の例(i-PRO カメラ)
入力画像として、 https://pixabay.com から取得した下記動画をテストに使用させていただきました。商用利用無料、帰属表示必要なし、のコンテンツです。
PC上で再生表示する動画を i-PRO カメラで接写しているため、画質が荒いこと、認識精度が微妙なこと、はご容赦ください。
こちらの例の場合、人が一定より小さいと認識できないようでした。カメラをディスプレに近づけて人のサイズを大きくすることで、AIが人を認識できるようになりました。
別ページ紹介の「機能拡張ソフトウェア(WV-XAE200W)」でも同じ映像を使って評価していますが、こちらの評価では同じ映像で小さい人を認識できています。この比較からも専用商品である WV-XAE200WUX の画像認識性能の高さを再確認させていただきました。
以上です。というわけで、プログラムを1行も書くことなく i-PRO カメラとPCを接続して MobileNetV1-SSD を実行することができました。
NOTE
プログラム "run_ssd_live_demo.py" 中で i-PRO カメラからのキャプチャーを行っている部分は下記の箇所です。
cap = cv2.VideoCapture(sys.argv[4]) # capture from file
2018年に MobileNet v1 の後継モデルとして v2 が発表されました。(MobileNet V2 の原著論文)
MobileNet v1 の構想およびモデルを基礎にしながら、モジュールを大幅に改良したものです。
MobileNet v1 同様、分類・物体検出・セマンティックセグメンテーションを含む画像認識を、モバイル端末などの限られたリソース下で高精度で判別するモデルを作成することを目的として作成しています。
MobileNetV2 で利用されているモジュールは以下の3つです。本ページでは詳細を割愛します。詳しくは原著論文などを参照ください。
表現が異なるので単純比較できませんが、V1およびV2のアーキテクチャ構造比較です。類似する場所を同じ色でマーキングしてみました。
V1で「"Conv dw/s1" + "Conv/s1」のセットと V2の1階層が対応する、という感じで読むと概ね同じような構造であることを読み取れると思います。
MobileNetV2とMobileNetV1の物体検出性能を、COCOデータセット上で評価・比較した結果です。論文からの引用です。
mAP | 認識性能の平均値(mean Average Precision) |
Mult-Adds | 積和演算の回数 |
Parameters | 重みの数 |
以上の結果から、MobileNetV2 SSDLite は最も効率的なモデルであるだけでなく、COCOデータセット上で YOLOv2 を上回る20倍の効率性と10倍の小型化を実現していることを読み取れます。
V1、V2 の比較についても、V2は認識精度(mAP)を低下することなく計算量(MAdd)を約4割削減できていることがわかります。
引用元: MobileNet V2 の原著論文
MobileNetV2-SSD を PyTorch の環境で動かしてみます。
MobileNetV1-SSD 同様に pytorch-ssd に含まれていますので、これを取得して動作させてみます。
言語 : | Python, | 3.10.4 |
PyTorch, | 1.11.0+cpu | |
OS : | Windows 11 home, | 21H2 |
Windows 10 pro, | 21H2 | |
1. pytorch-ssd から git clone してソースコード一式を入手します。(前章と同じです。実施済みなら不要です。)
任意のフォルダで端末(コマンドプロンプト等)を起動して下記コマンドをインプットします。
$ git clone https://github.com/qfgaohao/pytorch-ssd.git
2. "git clone" したフォルダへ移動します。
$ cd pytorch-ssd
3. README.md 中の "Run the live MobileNetV2 SSD Lite demo" に記載の内容に従って下記を実行します。
下記 Google Drive を開いて、"mb2-ssd-lite-mp-0_686.pth" および "voc-model-labels.txt" の2つのファイルを取得して models フォルダに保存します。
https://drive.google.com/drive/folders/1pKn-RifvJGWiOx0ZCRLtCXM5GT5lAluu
NOTE
2023/3/11 の pytorch-ssd 更新によりモデルファイルの取得方法が変更になりました。
4. 下記コマンドを実行することで推論を実行します。
$ python run_ssd_live_demo.py mb2-ssd-lite models/mb2-ssd-lite-mp-0_686.pth models/voc-model-labels.txt
5. プログラムを動かした様子を以下に示します。
カメラはPC内蔵のカメラです。PyTorch は前述の通り CPU 版ですがかなり快適に動作できています。
[動画] プログラムを動作させた様子(PC 内蔵カメラ)
ちゃんと MobiletNetV2-ssd-lite で動作できていると思いますが、こちら映像を見るだけでは V1, V2 の違いはわからないですね。
私が触ってみた印象ですが、認識精度が若干向上して CPU 負荷も若干軽くなったという気がします。
MobileNetV2-SSD-lite を PyTorch の環境で動かしてみます。
本章では i-PRO カメラとPCを LAN 接続してリアルタイムで物体検知してみます。前章と同様に pytorch-ssd を使って行います。
言語 : | Python, | 3.10.4 |
PyTorch, | 1.11.0+cpu | |
OS : | Windows 11 home, | 21H2 |
Windows 10 pro, | 21H2 | |
1. pytorch-ssd から git clone してソースコード一式を入手します。(前章と同じです。実施済みなら不要です。)
任意のフォルダで端末(コマンドプロンプト等)を起動して下記コマンドをインプットします。
$ git clone https://github.com/qfgaohao/pytorch-ssd.git
2. "git clone" したフォルダへ移動します。
$ cd pytorch-ssd
3. README.md 中の "Run the live MobilenetV1 SSD demo" に記載の内容に従って下記を実行します。(前章と同じです。実施済みなら不要です。)
下記 Google Drive を開いて、"mb2-ssd-lite-mp-0_686.pth" および "voc-model-labels.txt" の2つのファイルを取得して models フォルダに保存します。
https://drive.google.com/drive/folders/1pKn-RifvJGWiOx0ZCRLtCXM5GT5lAluu
NOTE
2023/3/11 の pytorch-ssd 更新によりモデルファイルの取得方法が変更になりました。
4. 下記コマンドを入力してプログラムを起動します。ここでは4番目の引数として RTSP 表記で i-PRO カメラの接続を記載します。
{user-id}, {password}, {ip-address} の部分をご自身が使われる i-PRO カメラの設定に合わせて修正して実行してください。
その他 RTSP に関しては記事「RTSP で画像を取得する」を参照ください。
$ python run_ssd_live_demo.py mb2-ssd-lite models/mb2-ssd-lite-mp-0_686.pth models/voc-model-labels.txt rtsp://{user-id}:{password}@{ip-address}/MediaInput/stream_1
(例) python run_ssd_live_demo.py mb2-ssd-lite models/mb2-ssd-lite-mp-0_686.pth models/voc-model-labels.txt rtsp://admin:Admin12345@192.168.0.10/MediaInput/stream_1
5. プログラムを動かした様子を以下に示します。
PyTorch は前述の通り CPU 版ですがかなり快適に動作できています。
i-PRO カメラの設定を 10fps にしています。私のノートPC環境では 30fps 動作させると映像が少しずつ遅延していきました。AI処理なしに映像表示させると 30fps 表示できているので、AI処理に伴うCPU負荷に原因するものと分析します。GPU無しの環境、CPU 版での動作で Full-HD 画像を 10fps でAI処理できているのですから、私個人の見解ですが、 MobileNet は十分に軽量で高性能な AI だと考えます。
[動画] プログラムを動作させた様子(i-PRO カメラ)
ちゃんと MobiletNetV2-ssd-lite で動作できていると思いますが、こちら映像を見るだけでは V1, V2 の違いはわからないですね。
私が触ってみた印象ですが、認識精度が若干向上して CPU 負荷も若干軽くなったという気がします。
以上です。というわけで、プログラムを1行も書くことなく i-PRO カメラとPCを接続して MobileNetV2-SSD も実行することができました。
本ページの紹介は Pytorch 動作を "CPU" として説明していますが、GPU(CUDA)で動作させた場合に必要となるソースコード修正について参考記載します。
MobileNetV1 については CUDA 環境で問題なく動作したのですが、MobileNetV2 について私の環境では下記修正を行う必要がありました。
対象ファイルは "vision/ssd/mobilenet_v2_ssd_lite.py" です。
2019年に MobileNet v2 の後継モデルとして v3 が発表されました。(MobileNet V3 の原著論文)
MobileNetV3 の要点は下記2つの技術です。本ページでは詳細を割愛します。詳しくは原著論文などを参照ください。
MobileNetV3 は Large と Small の2つのモデルを報告しています。アーキテクチャ構造を以下に示します。
MobileNetV3 の物体検出性能を、COCOデータセット上で評価・比較した結果です。論文からの引用です。
mAP | 認識性能の平均値(mean Average Precision) |
Mult-Adds | 積和演算の回数 |
Parameters | 重みの数 |
上記結果から V3 (Large) は、V1,V2 と同等の認識性能(mAP)を保持しながら、V1 の約半分、V2 の約7割の演算量(MAdds)という軽量なモデルを実現したと読み取れます。
V3-Small は Large のさらに半分の演算量を実現してますが認識性能は相応に低下するようです。
MobileNetV3-SSD-Lite は PyTorch に組み込まれていました。"ssdlite320_mobilenet_v3_large" というモジュールです。同様に学習済みモデルも Pytorch 環境のみで取得可能です。
本章では Pytorch および "ssdlite320_mobilenet_v3_large" を使って MobileNetV3-SSD-Lite を動かしてみたいと思います。
("ssdlite320_mobilenet_v3_large" のインプットサイズはファイル名記載の通り 320x320 にアレンジされているように見えます。詳細は割愛します。)
MobileNetV3-SSD-Lite は PyTorch に組み込まれていました。"ssdlite320_mobilenet_v3_large" というモジュールです。同様に学習済みモデルも Pytorch 環境のみで取得可能です。
本節では Pytorch および "ssdlite320_mobilenet_v3_large" を使って MobileNetV3-SSD-Lite を動かしてみたいと思います。
("ssdlite320_mobilenet_v3_large" のインプットサイズはファイル名記載の通り 320x320 にアレンジされているように見えます。詳細は割愛します。)
PyTorch の資料を参考に、JPEGファイルを読み込んで物体認識する Python プログラムを作成してみます。
参考にする元資料は
こちら (Object Detection) です。
この元資料の "fasterrcnn_resnet50_fpn_v2" を "ssdlite320_mobilenet_v3_large"
へ変更して、課題ある部分をさらに追加修正する、という感じでやってみます。
学習済みモデルは COCO dataset を使って学習しているので、このプログラムは下記 91クラス を検知します。
このプログラムを初めて実行するとき、このプログラムは学習済みモデルのダウンロードを行うため、プログラム起動に多くの時間を待つ必要があるでしょう。
1: person 2: bicycle 3: car 4: motorcycle 5: airplane 6: bus 7: train 8: truck 9: boat 10: traffic light 11: fire hydrant 12: street sign* 13: stop sign 14: parking meter 15: bench 16: bird 17: cat 18: dog 19: horse 20: sheep 21: cow 22: elephant 23: bear 24: zebra 25: giraffe 26: hat 27: backpack 28: umbrella 29: shoe 30: eye glasses 31: handbag 32: tie 33: suitcase 34: frisbee 35: skis 36: snowboard 37: sports ball 38: kite 39: baseball bat 40: baseball glove 41: skateboard 42: surfboard 43: tennis racket 44: bottle 45: plate 46: wine glass 47: cup 48: fork 49: knife 50: spoon 51: bowl 52: banana 53: apple 54: sandwich 55: orange 56: broccoli 57: carrot 58: hot dog 59: pizza 60: donut 61: cake 62: chair 63: couch 64: potted plant 65: bed 66: mirror 67: dining table 68: window 69: desk 70: toilet 71: door 72: tv 73: laptop 74: mouse 75: remote 76: keyboard 77: cell phone 78: microwave 79: oven 80: toaster 81: sink 82: refrigerator 83: blender 84: book 85: clock 86: vase 87: scissors 88: teddy bear 89: hair drier 90: toothbrush 91: hair brush
言語 : | Python, | 3.10.4 |
PyTorch, | 1.12.1+cpu | |
OS : | Windows 11 home, | 21H2 |
Windows 10 pro, | 21H2 | |
["run_mobilenetv3-ssdlite_jpeg_demo.py"]
''' [Abstract] Create a python program that detects objects in JPEG images using the trained AI model of "MobileNetV3 SSD-Lite". "MobileNetV3 SSD-Lite" の学習済みAIモデルを使用して、JPEG画像を対象に物体検知する Python プログラムを作成します。 [Details] This program uses pytorch "ssdlite320_mobilenet_v3_large" and pre-trained model. The program detects 91 classes because the trained model is trained using the COCO dataset. When you run this program for the first time, you will have to wait a lot of time to start the program, as it downloads the trained model. このプログラムは pytorch の "ssdlite320_mobilenet_v3_large" および 学習済みモデルを使用します。 学習済みモデルは COCO dataset を使って学習しているので、このプログラムは91クラスを検知します。 このプログラムを初めて実行するとき、このプログラムは学習済みモデルのダウンロードを行うため、あなたはプログラム起動に多くの時間を待つ必要があるでしょう。 [Library install] cv2: pip install opencv-python pytorch: pip install torch torchvision torchaudio [Reference URL] https://pytorch.org/vision/main/models.html#object-detection https://pytorch.org/vision/0.11/auto_examples/plot_visualization_utils.html#visualizing-bounding-boxes ''' from pathlib import Path from torchvision.io.image import read_image from torchvision.models.detection import ssdlite320_mobilenet_v3_large, SSDLite320_MobileNet_V3_Large_Weights from torchvision.utils import draw_bounding_boxes from torchvision.transforms.functional import to_pil_image img = read_image(str(Path('assets') / 'dog1.jpg')) # Step 1: Initialize model with the best available weights weights = SSDLite320_MobileNet_V3_Large_Weights.DEFAULT model = ssdlite320_mobilenet_v3_large(weights=weights) model = model.eval() # Step 2: Initialize the inference transforms preprocess = weights.transforms() # Step 3: Apply inference preprocessing transforms batch = [preprocess(img)] # Step 4: Use the model and visualize the prediction prediction = model(batch)[0] score_threshold = 0.5 labels = [weights.meta["categories"][class_index] + f": {score_int:.2f}" for class_index, score_int in zip(prediction["labels"], prediction["scores"]) if score_int > score_threshold] boxes = prediction["boxes"][prediction["scores"] > score_threshold] box = draw_bounding_boxes(img, boxes=boxes, labels=labels, colors="red", width=4, font='arial.ttf', font_size=30) im = to_pil_image(box.detach()) im.show()
たったこれだけのソースコードで物体検知を実現できます。学習済みモデルのダウンロードを含みますので、必ずインターネットへ接続できる環境で実行してください。
動作結果はこちらです。
評価画像として、 https://pixabay.com 提供の画像を使用させていただきました。商用利用無料、帰属表示必要なし、の画像です。
https://pixabay.com/ja/photos/マルタ語-犬-子犬-小型犬-1123016/
[注意] 上記プログラムを実行する際は、ご自身で画像を準備またはダウンロードして事前に "assets" フォルダに "dog1.jpg" の名称で保存してください。
学習済みモデルは下記に保存されます。'~' はログインしているユーザーのホームディレクトリを意味します。
Where are my downloaded models saved?
The locations are used in the order of
- Calling hub.set_dir(<PATH_TO_HUB_DIR>)
- $TORCH_HOME/hub, if environment variable TORCH_HOME is set.
- $XDG_CACHE_HOME/torch/hub, if environment variable XDG_CACHE_HOME is set.
- ~/.cache/torch/hub
私の場合は下記に ssdlite320_mobilenet_v3_large_coco-a79551df.pth というファイルを保存していました。約13MBのファイルサイズでした。
"~\.cache\torch\hub\checkpoints\ssdlite320_mobilenet_v3_large_coco-a79551df.pth"
4-1 で作成した JPEG 画像を対象に物体検知するプログラムを元に、ここではPC内蔵カメラの映像をライブで物体検知するプログラムを作成してみます。
PC内蔵カメラからの映像取得は OpenCV を使って行います。
言語 : | Python, | 3.10.4 |
PyTorch, | 1.12.1+cpu | |
OS : | Windows 11 home, | 21H2 |
Windows 10 pro, | 21H2 | |
ポイント
OpenCV 形式で取得した画像を PyTorch が扱える形式へ変換する必要があります。
["run_mobilenetv3-ssdlite_live_pc-cam_demo.py"]
''' [Abstract] Create a python program to detect objects in the camera live video using the trained AI model of "MobileNetV3 SSD-Lite". "MobileNetV3 SSD-Lite" の学習済みAIモデルを使用して、カメラライブ映像を物体検知する Python プログラムを作成してみます。 [Details] This program uses pytorch "ssdlite320_mobilenet_v3_large" and pre-trained model. The program detects 91 classes because the trained model is trained using the COCO dataset. When you run this program for the first time, you will have to wait a lot of time to start the program, as it downloads the trained model. このプログラムは pytorch の "ssdlite320_mobilenet_v3_large" および 学習済みモデルを使用します。 学習済みモデルは COCO dataset を使って学習しているので、このプログラムは91クラスを検知します。 このプログラムを始めて実行するとき、このプログラムは学習済みモデルのダウンロードを行うため、あなたはプログラム起動に多くの時間を待つ必要があるでしょう。 [Library install] cv2: pip install opencv-python pytorch: pip install torch torchvision torchaudio ''' import cv2 import torch from torchvision.models.detection import ssdlite320_mobilenet_v3_large, SSDLite320_MobileNet_V3_Large_Weights from torchvision.transforms.functional import convert_image_dtype from torchvision import transforms # Step 1: Initialize model with the best available weights weights = SSDLite320_MobileNet_V3_Large_Weights.DEFAULT model = ssdlite320_mobilenet_v3_large(weights=weights) model = model.eval() # Step 2: Initialize the inference transforms preprocess = weights.transforms() # Initialize variables. cap = cv2.VideoCapture(0) # Capture from camera. #cap.set(3, 1920) # Set video stream frame width. Remove '#' and change the value according to your needs. #cap.set(4, 1080) # Set video stream frame height. Remove '#' and change the value according to your needs. winname = "Annotated" # Window title. # Exception definition. BackendError = type('BackendError', (Exception,), {}) def IsWindowVisible(winname): ''' [Abstract] Check if the target window exists. 対象ウィンドウが存在するかを確認する。 [Param] winname : Window title [Return] True : exist 存在する False : not exist 存在しない [Exception] BackendError : ''' try: ret = cv2.getWindowProperty(winname, cv2.WND_PROP_VISIBLE) if ret == -1: raise BackendError('Use Qt as backend to check whether window is visible or not.') return bool(ret) except cv2.error: return False while True: # Capture image by opencv. ret, orig_image = cap.read() if orig_image is None: continue # Convert image from BGR to RGB. rgb_image = cv2.cvtColor(orig_image, cv2.COLOR_BGR2RGB) # Convert image from numpy.ndarray to torchvision image format. rgb_image = rgb_image.transpose((2, 0, 1)) rgb_image = rgb_image / 255.0 rgb_image = torch.FloatTensor(rgb_image) # Step 3: Apply inference preprocessing transforms batch = [preprocess(rgb_image)] # Step 4: Use the model and visualize the prediction with torch.no_grad(): prediction = model(batch)[0] score_threshold = 0.5 labels = [weights.meta["categories"][class_index] + f": {score_int:.2f}" for class_index, score_int in zip(prediction["labels"], prediction["scores"]) if score_int > score_threshold] boxes = prediction["boxes"][prediction["scores"] > score_threshold] # Draw result. for box, label in zip(boxes, labels): cv2.rectangle( orig_image, # Image. (int(box[0]), int(box[1])), # Vertex of the rectangle. (int(box[2]), int(box[3])), # Vertex of the rectangle opposite to pt1. (255, 255, 0), # Color. 4 ) # Line type. cv2.putText( orig_image, # Image. label, # Text string to drawn. (int(box[0])+20, int(box[1])+40), # Bottom-left corner of the text string in the image. cv2.FONT_HERSHEY_SIMPLEX, # Font face. - フォント種別 0.8, # Font scale. (255, 0, 255), # Color. 2) # Line type. # Display video. cv2.imshow(winname, orig_image) # Press the "q" key to finish. if cv2.waitKey(1) & 0xFF == ord('q'): break # Exit the program if there is no specified window. if not IsWindowVisible(winname): break cap.release() cv2.destroyAllWindows()
[動画] プログラムを動作させた様子(PC 内蔵カメラ)
4-1-2 で作成したプログラムを元に i-PRO カメラと接続してカメラ映像をライブで物体検知するプログラムを作成してみます。
cv2.VideoCapture の引数を "0" から RTSP表記 へ変更するだけです。
言語 : | Python, | 3.10.4 |
PyTorch, | 1.12.1+cpu | |
OS : | Windows 11 home, | 21H2 |
Windows 10 pro, | 21H2 | |
ポイント
cv2.VideoCapture 関数の引数として RTSP と呼ばれる表記でネットワークカメラとの接続情報を渡します。
この表記方法はネットワークカメラによって異なります。下記サンプルソースコードの表記は i-PRO カメラで使用されている表記です。
"user-id", "password", "host" の部分をご自身が使われる i-PRO カメラの設定に合わせて修正してください。
その他 RTSP に関しては記事「RTSP で画像を取得する」を参照ください。
["run_mobilenetv3-ssdlite_live_i-pro-com_demo.py"]
''' [Abstract] Create a python program to detect objects in the camera live video using the trained AI model of "MobileNetV3 SSD-Lite". "MobileNetV3 SSD-Lite" の学習済みAIモデルを使用して、カメラライブ映像を物体検知する Python プログラムを作成してみます。 [Details] This program uses pytorch "ssdlite320_mobilenet_v3_large" and pre-trained model. The program detects 91 classes because the trained model is trained using the COCO dataset. When you run this program for the first time, you will have to wait a lot of time to start the program, as it downloads the trained model. このプログラムは pytorch の "ssdlite320_mobilenet_v3_large" および 学習済みモデルを使用します。 学習済みモデルは COCO dataset を使って学習しているので、このプログラムは91クラスを検知します。 このプログラムを始めて実行するとき、このプログラムは学習済みモデルのダウンロードを行うため、あなたはプログラム起動に多くの時間を待つ必要があるでしょう。 [Library install] cv2: pip install opencv-python pytorch: pip install torch torchvision torchaudio ''' import cv2 import torch from torchvision.models.detection import ssdlite320_mobilenet_v3_large, SSDLite320_MobileNet_V3_Large_Weights from torchvision.transforms.functional import convert_image_dtype from torchvision import transforms # Initialize variables. user_id = "user-id" # Change to match your camera setting user_pw = "password" # Change to match your camera setting host = "192.168.0.10" # Change to match your camera setting resolution = "1920x1080" # Resolution framerate = 5 # Framerate winname = "Annotated" # Window title. # Step 1: Initialize model with the best available weights weights = SSDLite320_MobileNet_V3_Large_Weights.DEFAULT model = ssdlite320_mobilenet_v3_large(weights=weights) model = model.eval() # Step 2: Initialize the inference transforms preprocess = weights.transforms() # Capture from camera. url = f"rtsp://{user_id}:{user_pw}@{host}/MediaInput/stream_1" # H.264/H.265 #url = f"http://{user_id}:{user_pw}@{host}/cgi-bin/nphMotionJpeg?Resolution={resolution}&Quality=Standard&Framerate={framerate}" # MJPEG cap = cv2.VideoCapture(url) # Exception definition. BackendError = type('BackendError', (Exception,), {}) def IsWindowVisible(winname): ''' [Abstract] Check if the target window exists. 対象ウィンドウが存在するかを確認する。 [Param] winname : Window title [Return] True : exist 存在する False : not exist 存在しない [Exception] BackendError : ''' try: ret = cv2.getWindowProperty(winname, cv2.WND_PROP_VISIBLE) if ret == -1: raise BackendError('Use Qt as backend to check whether window is visible or not.') return bool(ret) except cv2.error: return False while True: # Capture image by opencv. ret, orig_image = cap.read() if orig_image is None: continue # Convert image from BGR to RGB. rgb_image = cv2.cvtColor(orig_image, cv2.COLOR_BGR2RGB) # Convert image from numpy.ndarray to torchvision image format. rgb_image = rgb_image.transpose((2, 0, 1)) rgb_image = rgb_image / 255.0 rgb_image = torch.FloatTensor(rgb_image) # Step 3: Apply inference preprocessing transforms batch = [preprocess(rgb_image)] # Step 4: Use the model and visualize the prediction with torch.no_grad(): prediction = model(batch)[0] score_threshold = 0.5 labels = [weights.meta["categories"][class_index] + f": {score_int:.2f}" for class_index, score_int in zip(prediction["labels"], prediction["scores"]) if score_int > score_threshold] boxes = prediction["boxes"][prediction["scores"] > score_threshold] # Draw result. for box, label in zip(boxes, labels): cv2.rectangle( orig_image, # Image. (int(box[0]), int(box[1])), # Vertex of the rectangle. (int(box[2]), int(box[3])), # Vertex of the rectangle opposite to pt1. (255, 255, 0), # Color. 4 ) # Line type. cv2.putText( orig_image, # Image. label, # Text string to drawn. (int(box[0])+20, int(box[1])+40), # Bottom-left corner of the text string in the image. cv2.FONT_HERSHEY_SIMPLEX, # Font face. - フォント種別 0.8, # Font scale. (255, 0, 255), # Color. 2) # Line type. # Display video. cv2.imshow(winname, orig_image) # Press the "q" key to finish. if cv2.waitKey(1) & 0xFF == ord('q'): break # Exit the program if there is no specified window. if not IsWindowVisible(winname): break cap.release() cv2.destroyAllWindows()
[動画] プログラムを動作させた様子(i-PRO カメラ、5fps)
NOTE
軽いとはいえ MobileNetV3 もそれなりにCPUを使用します。あなたの環境に合わせてカメラ映像のフレームレートを調節してください。多くの場合で 10fps または 5fps ぐらいに設定する必要があると思います。
物体検知を別プロセスで処理する(参考記事)ことで映像をフルレート表示するという方法もあります。よろしければ試してみてください。
NOTE
私の環境では V3 より V1、V2 の方が動作が軽い印象です。V1、V2 サンプルは10fpsで動作しましたが、V3 は5fpsまでカメラ設定を下げる必要がありました。
V1、V2サンプルはVOCデータセットでクラス数が20です。一方、V3サンプルはCOCOデータセットでクラス数が91という違いがあります。
加えて、V1、V2サンプルの入力画像サイズは 300x300 ですが、V3サンプルは 320x320 という違いもあります。そもそもベースとなっているプログラムが異なります。
以上の理由から、V1、V2、V3 を適正に比較評価できているわけでないこと、ご承知ください。ちゃんと同じ条件で比較したら V3 がやはりもっとも高性能という結果になるのではと期待しています。(クラス数の比が演算数にそのまま影響あるとすると概ね妥当な結果かな、と思っています。)
本ページの紹介は Pytorch 動作を "CPU" として説明していますが、私の環境で GPU(CUDA)で動作させた場合の概況について参考記載します。
上記ソースコードから device を "cuda:0" へ変更するためのソースコード修正を行うことで、私の環境では特にエラーなど発生することなく CUDA 環境で動作させることができました。しかし残念ながら CPU 動作からパフォーマンス向上を確認することができませんでした。私の実現方法に課題があるのか、または PyTorch 側に問題があるのか、問題の切り分けをまだできておりません。
進展あればこちらへ追記していきたいと思います。
MobilenetV3 は pytorch-ssd に含まれていますが、学習済みモデルを提供していませんでした。残念。
折角なので、私自身により学習を実施してみました。皆さんが期待するほどの認識性能に達していないかもしれませんが、本ページから私が作成した学習済みデータをダウンロードできるようにしました。このデータを使って MobileNet-SSD-V3 による推論を実行してみたいと思います。合わせてこの学習データを作成した手順についても参考記載します。
※ これで V1,V2,V3 を同等条件で動作比較できそうです。
"MobileNetV3-large-ssd-lite" の学習データを "VOC dataset" により作成してみます。
学習データ作成なので、本ページの当初ポリシーから外れますが、ここでは GPU を使用させていただきます。
言語 : | Python, | 3.10.7 |
PyTorch, | 1.12.1+cu116 | |
OS : | Windows 11 home, | 22H2 |
GPU: | NVIDIA GeForce GTX 1650, | GPUメモリ 4GB |
1. pytorch-ssd から git clone してソースコード一式を入手します。(前章と同じです。実施済みなら不要です。)
任意のフォルダで端末(コマンドプロンプト等)を起動して下記コマンドをインプットします。
$ git clone https://github.com/qfgaohao/pytorch-ssd.git
2. "git clone" したフォルダへ移動します。
$ cd pytorch-ssd
3. PASCAL VOC2007/2012 のデータセットをダウンロード、展開します。
■Linux の場合
$ cd data $ wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar $ wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar $ wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar $ tar -xvf VOCtrainval_11-May-2012.tar $ tar -xvf VOCtrainval_06-Nov-2007.tar $ tar -xvf VOCtest_06-Nov-2007.tar
■Windows の場合
Windows に標準では wget コマンドは無いため上記を実行してもエラーになります。ここでは、wget の代わりに bitsadmin コマンドで代用する方法を紹介します。
bitsadmin.exe の書き方:
bitsadmin.exe /transfer <ジョブ名> <URL> <保存先ファイル名(フルパス)>
上記内容を bitsadmin.exe で置き換えると以下のようになるので、Windows 環境の方はこちらで実施します。
c:\{作業フォルダ} の部分をご自身の環境に合わせて修正して実行してください。
$ cd data $ bitsadmin /TRANSFER htmldl http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar c:\{作業フォルダ}\data\VOCtrainval_11-May-2012.tar $ bitsadmin /TRANSFER htmldl http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar c:\{作業フォルダ}\data\VOCtrainval_06-Nov-2007.tar $ bitsadmin /TRANSFER htmldl http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar c:\{作業フォルダ}\data\VOCtest_06-Nov-2007.tar $ tar -xvf VOCtrainval_11-May-2012.tar $ tar -xvf VOCtrainval_06-Nov-2007.tar $ tar -xvf VOCtest_06-Nov-2007.tar
以上を実行すると、"data" フォルダの中に "VOCdevkit" というフォルダが作成されて、その中に "VOC2007" と "VOC2012" の2つのフォルダと大量のデータが作成されます。
4. データセットを再配置します。以下の順に実施します。
(1) "data" フォルダ中に "VOC0712" フォルダを作成し、この中に "VOC2007" と "VOC2012" を全てコピーします。
(2) "VOC0712" フォルダ中に "test" フォルダを作成し、このなかに "VOC2007" をコピーします。
5. 学習を実行します。私の場合は下記コマンドを実行しました。
$ cd .. $ python train_ssd.py --dataset_type voc --datasets ./data/VOC0712/VOC2007 ./data/VOC0712/VOC2012 --validation_dataset ./data/VOC0712/test/VOC2007 --net mb3-large-ssd-lite --scheduler cosine --lr 0.01 --t_max 200 --validation_epoch 5 --num_epochs 200 --batch_size 16
注意
Windows 環境でこの学習を行う場合、「5-1-2. 学習」に記載の内容に従って "train_ssd.py" および "vision/ssd/data_preprocessing.py" を修正する必要があります。
6. (参考) 中断してしまった学習を継続する方法
何かしらの理由でPCの電源をOffする必要があった、など学習を中断してしまった場合、下記コマンドを参考に前回学習結果を "--pretraind_ssd" として指定することである程度続きから学習を再開することができそうです。ただし完全な継続にはなりません。ある程度の学習回数後に概ね前回の状態に戻る感じです。私の感覚では Epoch で20回ぐらいかかりました。それでも全部やり直しすることと比較すればとても有効な手段だと思います。
$ python train_ssd.py --dataset_type voc --datasets ./data/VOC0712/VOC2007 ./data/VOC0712/VOC2012 --validation_dataset ./data/VOC0712/test/VOC2007 --net mb3-large-ssd-lite --pretrained_ssd models/mb3-large-ssd-lite-Epoch-NNN-Loss-N.NNNNNNNN.pth --scheduler cosine --lr 0.001 --t_max 200 --validation_epoch 5 --num_epochs 200 --batch_size 16
あとは学習が期待通りに進むのを期待して待ちます。
私が作成した学習済みデータを "こちら"
から取得可能です。
この学習済みデータの認識性能は以下の通りです。"eval_ssd.py" により測定した結果です。
Model: mb3-large-ssd-lite-mp-0_652.pth
Average Precision Per-class: aeroplane: 0.6858618154005621 bicycle: 0.7953144174658359 bird: 0.5944325029442169 boat: 0.5254286014580958 bottle: 0.29775074049868244 bus: 0.7695870498857185 car: 0.7172673114401424 cat: 0.8129718499191528 chair: 0.4989150543653392 cow: 0.5713323043655254 diningtable: 0.696122825413885 dog: 0.7490342862830122 horse: 0.8064323730818508 motorbike: 0.7576028544694091 person: 0.6886720836774618 pottedplant: 0.3843043827262724 sheep: 0.5665584224827491 sofa: 0.7792946515148939 train: 0.7889272422973491 tvmonitor: 0.5494204663075016 Average Precision Across All Classes:0.6517615617998829
MobileNetV3-large-SSD-lite を PyTorch の環境で動かしてみます。
PC 内蔵カメラの映像を接続してリアルタイムで物体検知してみます。
言語 : | Python, | 3.10.7 |
PyTorch, | 1.13.1+cpu | |
OS : | Windows 11 home, | 21H2 |
1. pytorch-ssd から git clone してソースコード一式を入手します。
任意のフォルダで端末(コマンドプロンプト等)を起動して下記コマンドをインプットします。
$ git clone https://github.com/qfgaohao/pytorch-ssd.git
2. "git clone" したフォルダへ移動します。
$ cd pytorch-ssd
3. 学習済みデータなどを取得します。
(1) "こちら" から学習済みデータ "mb3-large-ssd-lite-mp-0_652.pth" を取得して models フォルダに保存します。
(2) 下記 Google Drive から "voc-model-labels.txt" ファイルを取得して models フォルダに保存します。
https://drive.google.com/drive/folders/1pKn-RifvJGWiOx0ZCRLtCXM5GT5lAluu
4. 下記コマンドを実行することで推論を実行します。
$ python run_ssd_live_demo.py mb3-large-ssd-lite models/mb3-large-ssd-lite-mp-0_652.pth models/voc-model-labels.txt
学習済みモデルは VOC dataset を使って学習しているので、このプログラムは下記 20クラス を検知します。
1: aeroplane 2: bicycle 3: bird 4: boat 5: bottle 6: bus 7: car 8: cat 9: chair 10: cow 11: diningtable 12: dog 13: horse 14: motorbike 15: person 16: pottedplant 17: sheep 18: sofa 19: train 20: tvmonitor
5. プログラムを動かした様子を以下に示します。
カメラはPC内蔵のカメラです。PyTorch は前述の通り CPU 版ですがかなり快適に動作できています。
[動画] プログラムを動作させた様子(PC 内蔵カメラ)
MobileNetV3-large-SSD-lite を PyTorch の環境で動かしてみます。
i-PRO カメラとPCを LAN 接続してリアルタイムで物体検知してみます。
言語 : | Python, | 3.10.7 |
PyTorch, | 1.13.1+cpu | |
OS : | Windows 11 home, | 21H2 |
1. pytorch-ssd から git clone してソースコード一式を入手します。
任意のフォルダで端末(コマンドプロンプト等)を起動して下記コマンドをインプットします。
$ git clone https://github.com/qfgaohao/pytorch-ssd.git
2. "git clone" したフォルダへ移動します。
$ cd pytorch-ssd
3. 学習済みデータなどを取得します。
(1) "こちら" から学習済みデータ "mb3-large-ssd-lite-mp-0_652.pth" を取得して models フォルダに保存します。
(2) 下記 Google Drive から "voc-model-labels.txt" ファイルを取得して models フォルダに保存します。
https://drive.google.com/drive/folders/1pKn-RifvJGWiOx0ZCRLtCXM5GT5lAluu
4. 下記コマンドを実行することで推論を実行します。ここでは4番目の引数として RTSP 表記で i-PRO カメラの接続を記載します。
{user-id}, {password}, {ip-address} の部分をご自身が使われる i-PRO カメラの設定に合わせて修正して実行してください。
その他 RTSP に関しては記事「RTSP で画像を取得する」を参照ください。
$ python run_ssd_live_demo.py mb3-large-ssd-lite models/mb3-large-ssd-lite-mp-0_652.pth models/voc-model-labels.txt rtsp://{user-id}:{password}@{ip-address}/MediaInput/stream_1
(例) python run_ssd_live_demo.py mb3-large-ssd-lite models/mb3-large-ssd-lite-mp-0_652.pth models/voc-model-labels.txt rtsp://admin:Admin12345@192.168.0.10/MediaInput/stream_1
5. プログラムを動かした様子を以下に示します。
PyTorch は前述の通り CPU 版ですがかなり快適に動作できています。i-PRO カメラの設定を 10fps にしています。私のノートPC環境では 30fps 動作させると映像が少しずつ遅延していきました。AI処理なしに映像表示させると 30fps 表示できているので、AI処理に伴うCPU負荷に原因するものと分析します。GPU無しの環境、CPU 版での動作で Full-HD 画像を 10fps でAI処理できているのですから、私個人の見解ですが、 MobileNet は十分に軽量で高性能な AI だと考えます。
[動画] プログラムを動作させた様子(i-PRO カメラ)
以上です。というわけで、プログラムを1行も書くことなく i-PRO カメラとPCを接続して MobileNetV3-large-SSD-lite も実行することができました。
NOTE
この節では V1, V2 と同じ動作条件で比較することを目的に VOC dataset により学習を行った V3 学習データを作成し、動作させてみました。私の環境では V1、V2 と比較して V3 が最も動作が軽い印象です。認識するクラス数に比例して AI 処理負荷も重たくなる、ということだと推察します。ご自身で独自のAI学習データを作成する際は、必要なクラスのみでAI学習データを作成するようにすると良さそうです。
NOTE
続く5章は別ページ「物体検知 - MobileNet-SSD (学習編)」で記載します。
本ページで紹介のソースコードは、下記 github より取得できます。
下記 github のソースコードと本ページの内容は差異がある場合があります。
i-pro-corp/python-examples: Examples for i-PRO cameras. (github.com)
本ページの情報は、特記無い限り下記ライセンスで提供されます。
2023/10/20 | - | IP簡単設定ソフトウェア、IP Setting Software リンク先を更新, | 木下英俊 |
2023/5/12 | - | 「4-2._MobileNetV3-large-SSD-Lite」を追加, | 木下英俊 |
2023/4/12 | - | サイト pytorch-ssd の更新に伴う記事更新, | 木下英俊 |
2023/3/1 | - | 説明および表現を一部更新, | 木下英俊 |
2022/10/5 | - | 新規作成, | 木下英俊 |