【Python】画像から物体の種類、座標、幅、高さを検出する

Python
この記事は約4分で読めます。
(2021/9/11追記)
PyTorchとYOLOv5を使用して、物体の種類、座標、幅、高さを検出する方法
を書きました。準備と物体検出が簡単にできるので、こちらを参照することをおすすめします。

 

以前、keras-yolo3を使用して画像と動画から物体検出を行う方法を書きました。

【Python】keras-yolo3を使用して物体検出

keras-yolo3を利用すると画像から物体を検出して、検出した物体のクラス名と
確率を画像に出力してくれます。

Photo by rawpixel.com from Pexels

検出した物体を切り抜きたいときは、物体の座標、幅、高さが必要になります。
keras-yolo3を利用して物体の種類、左上の座標、幅、高さを求められるようにしてみます。

動作環境

  • Windows10
  • Python3.7.9
  • パッケージ管理にPipenvを使用

object-detection-keras-yolo3の利用方法

keras-yolo3のコードを利用して物体の種類、左上の座標、幅、高さを画像から検出する
Pythonスクリプトを作成しました。

GitHub - kazusapg/object-detection-keras-yolo3: This script uses keras-yolo3 to detect the top left coordinates, width and height of the objects in the image.
This script uses keras-yolo3 to detect the top left coordinates, width and height of the objects in the image. - GitHub - kazusapg/object-detection-keras-yolo3...

keras-yolo3のweight変換方法を踏襲しているので、検出できる物体は80種類です。
検出できる物体はこちらを参照してください。

インストール方法

object-detection-keras-yolo3のダウンロード

gitでcloneをする場合は以下を入力してください。

またはgithubのページ右側の緑色のclone or downloadをクリック後
Download ZIPを選択し、ファイルをダウンロードしてから解凍してください。

Pipenvを利用したインストール

Pipenvで仮想環境を作成する場合はコマンドプロンプトまたはPowerShellで
object-detection-keras-yolo3フォルダに移動後、pipenv installを入力します。
必要なパッケージをインストールした後に、pipenv shellで仮想環境に入ります。

YOLOv3 weightsの変換

YOLO: Real-Time Object DetectionからYOLOv3 weightsをダウンロードします。

YOLO: Real-Time Object Detection
You only look once (YOLO) is a state-of-the-art, real-time object detection system.

weightsファイルはページ内のhere(237MB)をクリックするとダウンロードできます。

You already have the config file for YOLO in the cfg/ subdirectory. You will have to download the pre-trained weight file here (237 MB).

ダウンロードしたweightsファイルをobject-detection-keras-yolo3フォルダに移動し、
下記のコマンドを入力してweightsファイルをkerasで利用できる形に変換します。

 

使用方法

  1. keras.yolo3からYOLOクラスをインポートします。
  2. objectsからget_objects_informationをインポートします。
  3. YOLOクラスのインスタンスを作成します。
  4. YOLOインスタンスと画像のファイルパスを引数としてget_objects_information関数を
    呼び出します。
  5. get_objects_information関数は、検出した物体ごとにdictionaryを生成し、
    生成したdictionaryをListに加えて返します。物体が検出できないときは空のListを返します。

get_objects_information関数内で生成されるdictionaryは
下記のキーを参照することで、それぞれの物体の情報を取得できます。

  • predicted_name 検出した物体のクラス名(人、自転車、車など)
  • x 検出した物体の左上座標のx位置
  • y 検出した物体の左上座標のy位置
  • width 検出した物体の幅
  • height 検出した物体の高さ

使用例

下記の画像から物体の情報を取得してみます。

Photo by rawpixel.com from Pexels

コードは以下になります。
画像はsample_picture.jpgという名前でpictureフォルダに保存されているとします。

画像内に人が2人写っているので、get_objects_information関数から
2つのdictionaryを含んだ状態でListが返ってきます。

List内のそれぞれのdictionaryを利用して、Pillowで保存した画像は下記の2つになります。

 

コメント

  1. じぇじぇ より:

    オリジナルの学習データで切り抜きしようとしていますが、エラーが出ます。
    オリジナルの学習はこちらを参考に実施しました。
    https://sleepless-se.net/2019/06/21/how-to-train-keras%e2%88%92yolo3/

    【やったこと】
    ・model_dataにオリジナルで作成した重みを入れた。
    ・『coco_classes.txt』内のクラス名をオリジナルと同じにした(6クラス)
    ・yolo.py の”model_image_size”をオリジナル学習時と合わせた(320,320)

    【エラー内容】
    ValueError: Dimension 0 in both shapes must be equal, but are 1 and 255. Shapes are [1,1,1024,33] and [255,1024,1,1]. for ‘Assign_360’ (op: ‘Assign’) with input shapes: [1,1,1024,33], [255,1024,1,1].

    対応方法をご存じでしたらご教示頂けないでしょうか。
    よろしくお願いいたします。

  2. じぇじぇ より:

    すみません。自己解決しました。
    model_dataにオリジナルで作成(学習)した重みを入れてませんでした。
    学習後のものを入れると正常に動きました。

  3. りた より:

    お忙しいところ失礼します。
    当記事からkeras-yolo面白く感じ始めてみたのですが、逆に画像であれば認識してる物体の領域の座標をテキストファイル等で出力。
    動画であれば認識した物体の領域を座標、秒数で出力することは可能なのでしょうか?
    分かりにくい文で申し訳ないのです、もしよろしければ返事をいただけると幸いです。

    • りたさん
      コメントありがとうございます。

      当記事内で紹介しているobject-detection-keras-yolo3ですが
      画像の座標しか検出できないので、オリジナルのkeras-yolo3を修正したほうが
      簡単です。

      keras-yolo3は動画と画像で物体検出ができるので、動画または画像の読み込み時に
      処理を振り分けてもらうのが良いと思います。

      座標を取得するためにyolo.py内のdetect_imageメソッドを変更する必要があります。

      • りた より:

        返信ありがとうございます。
        初心者ながら変更を行ってみたのですがうまくいかない状況です。
        大変申し訳ないのですが、参考になるコードを教えていただけないでしょうか?

        • object-detection-keras-yolo3内のyolo.pyのdetect_imageメソッドで
          検出した物体の左上の座標、幅、高さ、検出した物体のクラス名をまとめた
          dictをlistに詰めて返すようにしています。

          現在は画像内の物体しか検出できていませんが、こちらのコードを再利用してもらうと
          動画内の物体の座標も取得できると思いますので参考にしてみてください。