LoginSignup
6
7

More than 1 year has passed since last update.

PyTorchとYOLOV5を使って、カメラ付ノートPC(Windows)をオフラインのAI監視カメラにしてみました

Posted at

はじめに

  • 従来AIは学習させて使用するものでしたが、最近は汎用の学習済みモデルをダウンロードして使えるようになってます。この1つにYOLOV5があります。
  • これを利用して、カメラ付きノートPCをAI監視カメラ( = 物体認識するカメラ)にしてみました。
  • CPUだけでどれだけの速さになるか、試したかったためです。

工夫したこと

  1. ローカル化
     ネットワーク環境に縛られず、使えるようにしました。
  2. PCカメラから映像取り込み
     カメラからの映像を処理するようにしました。
  3. 推定検出の処理軽量化
     ハイスペックでないPCで動かすために、処理を減らしました。
    • 正確性は劣るが軽量なモデルyolov5sを使用
    • 推定時の画像を小さくして軽量化
  4. 検出結果の変数取得
     検出結果の矩形を取得し、ヒットエリアに入ったら、表示を変更するようにしました。

内容

1.PC環境

 実施したPC環境は以下のとおりです。GPUは計算に使ってません。

CPU Celeron N4100
メモリ 8GB LPDDR4

2.前準備

 Windowsで使えるようにするため、以下のツール / システムをインストールしました。
インストール時に参考にしたサイトも記載します。

1.python(使用したのはVer.3.7 )
 実行時のベースシステムです。
(参考)https://qiita.com/ssbb/items/b55ca899e0d5ce6ce963
2.pip(使用したのはVer.21.2.4 )
 他のツールをダウンロードする際に使うツールです。
(python3系ではバージョン3.4以降であれば、pythonのインストールと共にpipもインストールされます。)
(参考)https://gammasoft.jp/python/python-library-install/
3.OpenCV(使用したのはVer.4.5.3 )
 画像系処理するためのライブラリです。
(参考)https://qiita.com/ideagear/items/3f0807b7bde05aa18240
4.PyTorch(使用したのはVer.1.9.1+cpu )
 DeepLearningのライブラリです。CPUだけでやるため、Compute PlatformはCPUにしました。
(参考)https://qiita.com/thinknee/items/0c0c466928356c9a55af
5.YOLOV5(使用したのはVer.5.0 )
 物体検出のアルゴリズムです。
(参考)https://github.com/ultralytics/yolov5
5.yolov5s.pt
 使用する学習済みモデルです。
YOLOV5のフォルダで、例えば以下のコードを実行すると自動でダウンロードされます。
detect.py --source data/images/bus.jpg --weights yolov5s.pt
 次に組むpyファイルと同じフォルダに置きます。
 (このptファイルは、pyファイルを実行したときになければ、自動でダウンロードされます。)

3.pyファイルの作成

組んだコードは次のとおりです。

import sys
import cv2
import torch

#--- 検出する際のモデルを読込 ---
#model = torch.hub.load('ultralytics/yolov5','yolov5s')#--- webのyolov5sを使用
model = torch.hub.load("../yolov5",'yolov5s',source='local')#--- localのyolov5sを使用

#--- 検出の設定 ---
model.conf = 0.5 #--- 検出の下限値(<1)。設定しなければすべて検出
model.classes = [0] #--- 0:person クラスだけ検出する。設定しなければすべて検出
#print(model.names) #--- (参考)クラスの一覧をコンソールに表示

#--- 映像の読込元指定 ---
#camera = cv2.VideoCapture("../pytorch_yolov3/data/sample.avi")#--- localの動画ファイルを指定
camera = cv2.VideoCapture(0)                #--- カメラ:Ch.(ここでは0)を指定


#--- 画像のこの位置より左で検出したら、ヒットとするヒットエリアのためのパラメータ ---
pos_x = 240

while True:

#--- 画像の取得 ---
#  imgs = 'https://ultralytics.com/images/bus.jpg'#--- webのイメージファイルを画像として取得
#  imgs = ["../pytorch_yolov3/data/dog.png"] #--- localのイメージファイルを画像として取得
  ret, imgs = camera.read()              #--- 映像から1フレームを画像として取得

#--- 推定の検出結果を取得 ---
#  results = model(imgs) #--- サイズを指定しない場合は640ピクセルの画像にして処理
  results = model(imgs, size=160) #--- 160ピクセルの画像にして処理

#--- 出力 ---
#--- 検出結果を画像に描画して表示 ---
  #--- 各検出について
  for *box, conf, cls in results.xyxy[0]:  # xyxy, confidence, class

      #--- クラス名と信頼度を文字列変数に代入
      s = model.names[int(cls)]+":"+'{:.1f}'.format(float(conf)*100)

      #--- ヒットしたかどうかで枠色(cc)と文字色(cc2)の指定
      if int(box[0])>pos_x :
        cc = (255,255,0)
        cc2 = (128,0,0)
      else:
        cc = (0,255,255)
        cc2 = (0,128,128)

      #--- 枠描画
      cv2.rectangle(
          imgs,
          (int(box[0]), int(box[1])),
          (int(box[2]), int(box[3])),
          color=cc,
          thickness=2,
          )
      #--- 文字枠と文字列描画
      cv2.rectangle(imgs, (int(box[0]), int(box[1])-20), (int(box[0])+len(s)*10, int(box[1])), cc, -1)
      cv2.putText(imgs, s, (int(box[0]), int(box[1])-5), cv2.FONT_HERSHEY_PLAIN, 1, cc2, 1, cv2.LINE_AA)

  #--- ヒットエリアのラインを描画
  cv2.line(imgs, (pos_x, 0), (pos_x, 640), (128,128,128), 3)

  #--- 描画した画像を表示
  cv2.imshow('color',imgs)

#--- (参考)yolo標準機能を使った出力 ---
#  results.show()#--- yolo標準の画面表示
#  results.print()#--- yolo標準のコンソール表示

#--- (参考)yolo標準の画面を画像取得してopencvで表示 ---
#  pics = results.render()
#  pic = pics[0]
#  cv2.imshow('color',pic)

  #--- 「q」キー操作があればwhileループを抜ける ---
  if cv2.waitKey(1) & 0xFF == ord('q'):
    break

4.説明

1. ローカル化

 以下のhub関数のコードのところを1行目から2行目のように書き換え、ローカル処理にしました。

#model = torch.hub.load('ultralytics/yolov5','yolov5s')#--- webのyolov5sを使用
model = torch.hub.load("../yolov5",'yolov5s',source='local')#--- localのyolov5sを使用

2. PCカメラから映像取り込み

 以下のコードのところを1行目から2行目のように書き換え、カメラ画像を取り込むようにしました。

#camera = cv2.VideoCapture("../pytorch_yolov3/data/sample.avi")#--- localの動画ファイルを指定
camera = cv2.VideoCapture(0)                #--- カメラ:Ch.(ここでは0)を指定

3. 推定検出の処理軽量化

  • 正確性は劣るが軽量なモデルyolov5sを使用
     以下のコードでyolov5sを使うようにしました。
model = torch.hub.load("../yolov5",'yolov5s',source='local')#--- localのyolov5sを使用

 YOLOV5のモデルには、yolov5n、yolov5s、yolov5m、yolov5l、yolov5xなどがあります。
(参考)https://github.com/ultralytics/yolov5/releases

  • 推定時の画像を小さくして軽量化
     以下のコードのところを1行目から2行目のように書き換え、処理画像を荒く小さくしました。
#  results = model(imgs) #--- サイズを指定しない場合は640ピクセルの画像にして処理
  results = model(imgs, size=160) #--- 160ピクセルの画像にして処理

4. 検出結果の変数取得

 以下のコードで各検出の変数をfor文で取得しました。

  for *box, conf, cls in results.xyxy[0]:  # xyxy, confidence, class

 変数種類とこのコードにて代入される変数名の対応は下表のとおりです。

変数種類 変数名
矩形の左上角のX座標 box[0]
矩形の左上角のY座標 box[1]
矩形の右下角のX座標 box[2]
矩形の右下角のY座標 box[3]
クラスの番号 cls
推定の信頼度 conf

 これらの変数を利用して、後処理を変えることができます。
今回はヒットエリア(画面の左側)で検出したものは枠の色を変更するようにしました。

5.結果

 カメラ映像でも遅延が気にならない速さで処理できました。
ちなみに、results = model(imgs, size=160)のところでsize=160size=80にするともっと速く処理できますが、検出ミスがひどくなりました。逆にsize=320にすると遅延が気になるところまで遅くなりました。

参考

参考コード
https://github.com/ultralytics/yolov5/issues/36

6
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7