以前、keras-yolo3を使用して画像と動画から物体検出を行う方法を書きました。
keras-yolo3を利用すると画像から物体を検出して、検出した物体のクラス名と確率を画像に出力してくれます。

Photo by rawpixel.com from Pexels

検出した物体を切り抜きたいときは、物体の座標、幅、高さが必要になります。
keras-yolo3を利用して物体の種類、左上の座標、幅、高さを求められるようにしてみます。
動作環境 #
- Windows10
- Python3.7.9
- パッケージ管理にPipenvを使用
object-detection-keras-yolo3の利用方法 #
keras-yolo3のコードを利用して物体の種類、左上の座標、幅、高さを画像から検出するPythonスクリプトを作成しました。
This script uses keras-yolo3 to detect the top left coordinates, width and height of the objects in the image.
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
使用方法 #
- 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 | 検出した物体の高さ |
使用例 #
下記の画像から物体の情報を取得してみます。

コードは以下になります。
画像は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つになります。

