【Python】画像から物体の種類、座標、幅、高さを検出する
概要
(2021/9/11追記)PyTorchとYOLOv5を使用して、物体の種類、座標、幅、高さを検出する方法を書きました。
準備と物体検出が簡単にできるので、こちらを参照することをおすすめします。
以前、keras-yolo3を使用して画像と動画から物体検出を行う方法を書きました。
https://kazusa-pg.com/use-keras-yolo3/
keras-yolo3を利用すると画像から物体を検出して、検出した物体のクラス名と確率を画像に出力してくれます。

Photo by rawpixel.com from Pexels

検出した物体を切り抜きたいときは、物体の座標、幅、高さが必要になります。
keras-yolo3を利用して物体の種類、左上の座標、幅、高さを求められるようにしてみます。
動作環境
- Windows10
- Python3.7.9
- パッケージ管理にPipenvを使用
object-detection-keras-yolo3の利用方法
keras-yolo3のコードを利用して物体の種類、左上の座標、幅、高さを画像から検出するPythonスクリプトを作成しました。
https://github.com/kazusapg/object-detection-keras-yolo3
keras-yolo3のweight変換方法を踏襲しているので、検出できる物体は80種類です。
検出できる物体はこちらを参照してください。
https://github.com/kazusapg/object-detection-keras-yolo3/blob/master/model_data/coco_classes.txt
インストール方法
object-detection-keras-yolo3のダウンロード
gitでcloneをする場合は以下を入力してください。
1git clone https://github.com/kazusapg/object-detection-keras-yolo3.git
またはgithubのページ右側の緑色のclone or downloadをクリック後Download ZIPを選択し、
ファイルをダウンロードしてから解凍してください。
https://github.com/kazusapg/object-detection-keras-yolo3
Pipenvを利用したインストール
Pipenvで仮想環境を作成する場合はコマンドプロンプトまたはPowerShellで
object-detection-keras-yolo3フォルダに移動後、pipenv installを入力します。
必要なパッケージをインストールした後に、pipenv shellで仮想環境に入ります。
1cd object-detection-keras-yolo3
2pipenv install
3pipenv shell
YOLOv3 weightsの変換
YOLO: Real-Time Object DetectionからYOLOv3 weightsをダウンロードします。
https://pjreddie.com/darknet/yolo/
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で利用できる形に変換します。
1python keras_yolo3/convert.py keras_yolo3/yolov3.cfg yolov3.weights model_data/yolo.h5
使用方法
- keras.yolo3からYOLOクラスをインポートします。
- objectsからget_objects_informationをインポートします。
- YOLOクラスのインスタンスを作成します。
- YOLOインスタンスと画像のファイルパスを引数としてget_objects_information関数を呼び出します。
- 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フォルダに保存されているとします。
1from PIL import Image
2from keras_yolo3.yolo import YOLO
3from objects import get_objects_information
4
5if __name__ == '__main__':
6 yolo = YOLO()
7 image_path = "./picture/sample_picture.jpg"
8 objects_info_list = get_objects_information(yolo, image_path)
9 yolo.close_session()
10
11 img = Image.open(image_path)
12 count = 0
13 for object_info in objects_info_list:
14 class_name = object_info['predicted_name']
15 x = object_info['x']
16 y = object_info['y']
17 width = object_info['width']
18 height = object_info['height']
19 cropped_img = img.crop((x, y, x + width, y + height))
20 cropped_img.save("./picture/{}{}.jpg".format(class_name, count))
21 count = count + 1
画像内に人が2人写っているので、get_objects_information関数から2つのdictionaryを含んだ状態でListが返ってきます。
1[{'x': 102.010155, 'y': 395.04367, 'width': 530.84344,
2 'height': 500.70053, 'predicted_name': 'person'},
3 {'x': 700.43365, 'y': 400.91656, 'width': 433.38104,
4 'height': 494.5551, 'predicted_name': 'person'}]
List内のそれぞれのdictionaryを利用して、Pillowで保存した画像は下記の2つになります。

