メインコンテンツへスキップ
【Python】画像から物体の種類、座標、幅、高さを検出する

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

·4 分
Programming Python
かずさプログラマー
著者
かずさプログラマー
業務の作業自動化を行っています。Go、VBA、Pythonを主に使用しています。過去にはC#、VB.Net、JavaScriptも使用していました。
目次
(2021/9/11追記)PyTorchとYOLOv5を使用して、物体の種類、座標、幅、高さを検出する方法を書きました。 準備と物体検出が簡単にできるので、こちらを参照することをおすすめします。

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

【Python】keras-yolo3を使用して物体検出
·3 分
Programming Python

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

Photo by rawpixel.com from Pexels

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

動作環境
#

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

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

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

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.

Python
2
3

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

インストール方法
#

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

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

git clone https://github.com/kazusapg/object-detection-keras-yolo3.git

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

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

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

cd object-detection-keras-yolo3
pipenv install
pipenv shell

YOLOv3 weightsの変換
#

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

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で利用できる形に変換します。

python keras_yolo3/convert.py keras_yolo3/yolov3.cfg yolov3.weights model_data/yolo.h5

使用方法
#

  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 検出した物体の高さ

使用例
#

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

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

from PIL import Image
from keras_yolo3.yolo import YOLO
from objects import get_objects_information

if __name__ == '__main__':
    yolo = YOLO()
    image_path = "./picture/sample_picture.jpg"
    objects_info_list = get_objects_information(yolo, image_path)
    yolo.close_session()

    img = Image.open(image_path)
    count = 0
    for object_info in objects_info_list:
        class_name = object_info['predicted_name']
        x = object_info['x']
        y = object_info['y']
        width = object_info['width']
        height = object_info['height']
        cropped_img = img.crop((x, y, x + width, y + height))
        cropped_img.save("./picture/{}{}.jpg".format(class_name, count))
        count = count + 1

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

[{'x': 102.010155, 'y': 395.04367, 'width': 530.84344,
 'height': 500.70053, 'predicted_name': 'person'},
 {'x': 700.43365, 'y': 400.91656, 'width': 433.38104,
 'height': 494.5551, 'predicted_name': 'person'}]

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

関連記事

【Python】Seleniumでiframeの内容を操作する
·3 分
Programming Python
【Python】テキストファイルの文字コードを判別してファイルを開く
·3 分
Programming Python
【Python】keras-yolo3を使用して物体検出
·3 分
Programming Python