MENU

Python×YOLOで画像認識を始めよう:人物と犬を検出する手順を解説

  • URLをコピーしました!

※本ページはアフィリエイト広告を利用しています

Pythonと機械学習への興味が高まる中、画像認識技術への関心も急速に広がっています。

その中でも、YOLO(You Only Look Once)は、高速かつ高精度なオブジェクト検出が可能な技術として注目を集めています。

本記事では、Pythonを使ってYOLOを活用し、画像内の人物と犬を検出する方法をステップバイステップで解説します。

初心者の方でも理解しやすいように、必要なライブラリのインストールからプログラムの実行方法まで、実際のコードを元に詳しく説明します。機械学習やAIに興味がある方は、この記事を通じてYOLOの使い方をマスターしましょう。

目次

PythonでYOLOを使ってみよう!画像認識の基本

今回、画像のオブジェクト検出で使用するYOLOの概要について解説します。

1-1. YOLOとは?機械学習におけるオブジェクト検出の概要

YOLO(You Only Look Once)は、ディープラーニングを活用したオブジェクト検出アルゴリズムの一つです。他のオブジェクト検出手法と比較して、YOLOは画像を1回だけでオブジェクトを検出するため、高速な処理が可能です。リアルタイムでのオブジェクト検出が求められる自動運転やセキュリティシステムなど、さまざまな分野で利用されています。

1-2. YOLOのバージョン比較:YOLOv3から最新のYOLOv5まで

YOLOには複数のバージョンが存在し、最新のバージョンでは精度や速度が向上しています。YOLOv3は高い検出精度で広く使われていましたが、YOLOv4ではさらに最適化され、精度と速度のバランスが改善されました。そして、YOLOv5では使いやすさに加え、PyTorchベースでの実装が可能になり、Pythonでの開発がよりシンプルになりました。今回の記事では、最新であるYOLOv5を使用してオブジェクト検出を行います。

1-3. PythonでYOLOを使うメリットと活用事例

PythonでYOLOを使用することにより、ディープラーニングを利用した高度なオブジェクト検出を簡単に実装することができます。Pythonの豊富なライブラリを活用することで、データの前処理や結果の可視化も容易です。活用事例としては、防犯カメラでの異常検知、自動車の自動運転、産業用ロボットの物体検出など、多岐にわたります。

1-4. 必要なライブラリと環境構築:YOLOをPythonで始めるために

YOLOをPythonで使うためには、PyTorchやOpenCVなどのライブラリが必要です。PyTorchはディープラーニングのためのフレームワークで、YOLOの学習済みモデルをロードするために使用します。

また、OpenCVは画像処理ライブラリで、画像の読み込みや表示、バウンディングボックスの描画に使用します。環境構築の手順として、まずPythonがインストールされていることを確認し、必要なライブラリをpipでインストールします。

まず仮想環境を作成します。

python3 -m venv yolov5_env
source yolov5_env/bin/activate  # Linux/MacOS

続いて必要なライブラリをインストールします。

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
pip install opencv-python-headless  # OpenCVのインストール
pip install numpy
pip install pandas
pip install matplotlib
pip install requests
pip install tqdm  # プログレスバー用(オプション)

1-5. COCOデータセットとYOLOの事前学習モデルの関係

YOLOはCOCO(Common Objects in Context)データセットを使って事前学習されたモデルを提供しています。COCOデータセットは、80種類のオブジェクトクラスが含まれており、YOLOの学習済みモデルはこれらのクラスに対して高い検出精度を持っています。これにより、YOLOを使うだけで多くの一般的なオブジェクトを簡単に検出することができます。

PythonでYOLOを使って人物と犬を検出する方法

2-1-1. YOLOモデルのロードと初期化方法

YOLOv5を使うために、事前学習済みのYOLOモデルをロードします。PyTorchを使用して、モデルをロードするためのコードは以下のようになります。

import torch

# YOLOv5モデルのロード
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)

このコードを実行すると、YOLOv5sモデルがロードされ、オブジェクト検出に使用できるようになります。

2-1-2. ユーザーからの画像パス入力と検出対象の設定

次に、ユーザーが検出対象となる画像ファイルのパスを入力できるようにします。input()関数を使用して、ユーザーからの入力を受け付け、指定された画像ファイルのパスを取得します。

image_path = input("検出対象の画像ファイルのパスを入力してください: ").strip()

このコードにより、ユーザーは検出に使用する画像ファイルのパスを入力することができます。

2-1-3. 特定のオブジェクトを検出するためのYOLO推論の実行

YOLOモデルを使って画像内のオブジェクトを検出します。今回は特定のオブジェクトである「人間」と「犬」にフォーカスして検出を行います。

# YOLOによる推論
results = model(image_path)

# 検出対象のクラス(人間と犬)の指定
target_classes = ['person', 'dog']

このコードにより、画像内の「人間」と「犬」のみが検出されるようにフィルタリングされます。

2-1-4. 検出されたオブジェクトにバウンディングボックスを描画する方法

検出されたオブジェクトに対してバウンディングボックスを描画し、画像内のどこにオブジェクトが存在するかを可視化します。OpenCVを使用して、検出されたオブジェクトの位置にバウンディングボックスを描画します。

import cv2

# 検出結果の描画
for det in results.xyxy[0]:
    x1, y1, x2, y2, conf, cls = det
    label = f"{model.names[int(cls)]} {conf:.2f}"
    cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)
    cv2.putText(image, label, (int(x1), int(y1) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

このコードにより、検出された「人間」や「犬」の周囲にバウンディングボックスが描画され、検出結果が視覚的に確認できます。

2-1-5. 検出結果の画像をファイルに保存する手順

検出結果を保存するためには、OpenCVのimwrite関数を使用します。これにより、バウンディングボックスが描画された画像をファイルとして保存します。

# 検出結果の画像を保存
output_path = "detected_image.jpg"
cv2.imwrite(output_path, image)
print(f"検出結果の画像を保存しました: {output_path}")

このコードにより、検出結果の画像がdetected_image.jpgとして保存されます。

2-1-6. 検出結果をリアルタイムで確認するためのOpenCVの活用

リアルタイムで検出結果を確認するために、OpenCVのimshowを使って画像を表示します。これは、検出結果をすぐに確認したい場合に便利です。

# 検出結果の表示
cv2.imshow("Detection Results", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

このコードにより、検出結果を画面に表示し、ユーザーが任意のキーを押すまでウィンドウが開いたままになります。

2-1-7. 複数画像の連続処理とユーザーインタラクションの実装

このプログラムは、複数の画像を連続して処理できるように設計されています。ユーザーからのインプットを待ち、続けて他の画像を処理するかどうかを選択できるようにしています。

while True:
    image_path = input("検出対象の画像ファイルのパスを入力してください: ").strip()
    # ...(検出処理)...
    cont = input("他の画像を処理しますか? (y/n): ").strip().lower()
    if cont != 'y':
        break

このループにより、ユーザーは複数の画像を処理し続けることが可能になります。

2-2.全体のソースコード

今回作成した全体のソースコードは以下の通りです。

import torch
import cv2
import os
import numpy as np

def load_model():
    """
    YOLOv5モデルのロード(YOLOv5sを使用)
    """
    try:
        # 環境変数 TORCH_HOME を設定
        os.environ['TORCH_HOME'] = '/home/win/torch_cache'
        # Torch Hub のキャッシュディレクトリを設定
        torch.hub.set_dir('/home/win/torch_cache/hub')

        print("YOLOv5モデルをロード中...")
        model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True, force_reload=True)
        print("モデルのロードが完了しました。")
        return model
    except Exception as e:
        print(f"モデルのロード中にエラーが発生しました: {e}")
        exit(1)

def get_image_path():
    """
    ユーザーから画像パスを取得し、存在を確認する
    """
    while True:
        image_path = input("検出対象の画像ファイルのパスを入力してください: ").strip('"').strip("'")
        if os.path.isfile(image_path):
            return image_path
        else:
            print(f"エラー: 指定された画像ファイルが存在しません: {image_path}")
            retry = input("もう一度入力しますか? (y/n): ").strip().lower()
            if retry != 'y':
                print("プログラムを終了します。")
                exit(1)

def filter_detections(results, target_classes):
    """
    検出結果から指定したクラスのみをフィルタリングする
    """
    # COCOデータセットのクラス名を取得
    class_names = results.names

    # ターゲットクラスのIDを取得
    target_class_ids = [id for id, name in class_names.items() if name in target_classes]

    # 検出結果のフィルタリング
    if len(results.xyxy[0]) == 0:
        return None, target_class_ids

    # TensorをNumPy配列に変換
    detections = results.xyxy[0].cpu().numpy()

    # クラスIDでフィルタリング
    filtered_detections = detections[np.isin(detections[:, -1], target_class_ids)]
    return filtered_detections, target_class_ids

def draw_boxes(image, detections, class_names):
    """
    検出されたオブジェクトにバウンディングボックスとラベルを描画する
    """
    for det in detections:
        x1, y1, x2, y2, conf, cls = det
        label = f"{class_names[int(cls)]} {conf:.2f}"
        x1, y1, x2, y2 = map(int, [x1, y1, x2, y2])
        # バウンディングボックスを描画
        cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
        # ラベルを描画
        cv2.putText(image, label, (x1, y1 - 10), 
                    cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
    return image

def save_detected_image(image_path, image):
    """
    検出結果の画像をファイルとして保存する
    """
    # 元のファイル名と拡張子を取得
    base, ext = os.path.splitext(image_path)
    # 新しいファイル名を作成(例: image_detected.jpg)
    output_path = f"{base}_detected{ext}"
    
    # 画像を保存
    try:
        cv2.imwrite(output_path, image)
        print(f"検出結果の画像を保存しました: {output_path}")
    except Exception as e:
        print(f"画像の保存中にエラーが発生しました: {e}")

def main():
    # モデルのロード
    model = load_model()

    while True:
        # ユーザーから画像パスを取得
        image_path = get_image_path()

        # 推論の実行
        print(f"画像を処理中: {image_path}")
        try:
            results = model(image_path)
        except Exception as e:
            print(f"推論中にエラーが発生しました: {e}")
            continue

        # ターゲットクラスの指定
        target_classes = ['person', 'dog']
        filtered_detections, target_class_ids = filter_detections(results, target_classes)

        # 結果の表示
        if filtered_detections is not None and len(filtered_detections):
            print(f"検出されたオブジェクト ({', '.join(target_classes)}):")
            for det in filtered_detections:
                x1, y1, x2, y2, conf, cls = det
                class_name = model.names[int(cls)]
                print(f"- {class_name} (信頼度: {conf:.2f}) 座標: ({int(x1)}, {int(y1)}), ({int(x2)}, {int(y2)})")

            # 画像の読み込みとバウンディングボックスの描画
            image = cv2.imread(image_path)
            image = draw_boxes(image, filtered_detections, model.names)

            # 検出結果の画像を保存
            save_detected_image(image_path, image)

            # 結果画像の表示
            window_name = "Detection Results"
            cv2.imshow(window_name, image)
            print("検出結果の画像を表示しています。キーを押すと閉じます。")
            cv2.waitKey(0)
            cv2.destroyAllWindows()
        else:
            print(f"指定されたクラス({', '.join(target_classes)})のオブジェクトは検出されませんでした。")

        # 続行確認
        cont = input("他の画像を処理しますか? (y/n): ").strip().lower()
        if cont != 'y':
            print("プログラムを終了します。")
            break

if __name__ == "__main__":
    main()

PythonでYOLOプログラムを実行する方法

ここからは実際に作成したプログラムを実行してオブジェクト検出を行う手順を解説します。

3-1. プログラムファイルの作成と保存:コードの準備

作成したコードをテキストエディタにコピーし、yolov5-detect-and-save.pyとして保存します。このファイルが実行可能なプログラムとなります。保存場所は任意ですが、後で実行しやすいディレクトリに保存しておくと便利です。

3-2. コマンドラインでの実行方法:画像パスの入力と推論

コマンドプロンプトまたはターミナルを開き、スクリプトが保存されているディレクトリに移動します。その後、以下のコマンドを実行します。

python yolov5-detect-and-save.py

実行すると、画像ファイルのパスを入力するように求められます。画像パスを入力すると、プログラムがオブジェクト検出を実行します。

3-3. 推論結果の確認と保存された画像の確認手順

プログラムが正常に実行されると、指定した画像に対する検出結果が画面に表示され、同時に結果がファイルに保存されます。保存された画像ファイルを確認して、検出結果が期待通りであることを確認してください。

人物の検出

今回は以下のような人混みの画像を使用しました。

推論の結果、以下のようにファイルが生成されました。

かなり高精度に人物を検出できていることが確認できました。

犬の検出

今度は犬を検出してみます。犬と猫が映っている画像を指定して推論を実行します。

実行結果は以下のように犬だけを検出できました。

3-4. 検出精度の確認と結果の考察

結果画像を確認し、検出されたオブジェクトが期待通りかどうかを検証します。精度が低い場合や検出漏れがある場合、入力画像の品質やモデルのバージョン、パラメータの調整などを検討してみてください。

トラブルシューティング(発生するエラーの対策)

3-5. エラーが発生した場合の対処法:よくあるトラブルシューティング

エラーが発生した場合、以下の点を確認してください:

  • ライブラリが正しくインストールされているか
  • 画像ファイルのパスが正しいか
  • 対応している画像フォーマットか(JPEG, PNGなど)

モデルダウンロード時のパーミッションエラー

今回作成したプログラムでは推論前にYOLOのパラメータファイルをダウンロードしますが、その際以下のようなエラーが発生する場合があります。

Downloading https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt to yolov5s.pt...
ERROR: [Errno 13] Permission denied: 'yolov5s.pt.c1850430577748fd87b30c5f0487b94d.partial'
Re-attempting https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt to yolov5s.pt...
Warning: Failed to create the file yolov5s.pt: Permission denied
curl: (23) Failure writing output to destination

ERROR: Downloaded file 'yolov5s.pt' does not exist or size is < min_bytes=100000.0
yolov5s.pt missing, try downloading from https://github.com/ultralytics/yolov5/releases/v7.0

モデルのロード中にエラーが発生しました: [Errno 2] No such file or directory: 'yolov5s.pt'. Cache may be out of date, try force_reload=True or see https://docs.ultralytics.com/yolov5/tutorials/pytorch_hub_model_loading for help.

ダウンロードしようとしているフォルダに書き込み権限がないと発せします。

その場合は管理者権限でプログラムを実行してください。(フルパスでPythonを指定します)

sudo /home/win/anaconda3/envs/(仮想環境名)/bin/python yolov5-detect-and-save.py

まとめ:PythonでYOLOを使ってAIの世界を広げよう

PythonとYOLOを組み合わせることで、画像内のオブジェクトを効率的に検出し、画像認識の基本を学ぶことができます。今回の記事では、PythonでYOLOを使って人物と犬を検出する手順を詳しく解説しました。これにより、オブジェクト検出の仕組みやPythonでの実装方法について理解が深まったかと思います。

機械学習やAIに興味を持つ方にとって、YOLOは非常にパワフルなツールです。オブジェクト検出の基礎をマスターしたら、次のステップとしてリアルタイム処理やカスタムモデルの学習などに挑戦してみてください。PythonとYOLOを活用することで、AIの世界がさらに広がることでしょう。

ぜひ、この知識を活用してさまざまなプロジェクトにチャレンジし、AIの可能性を探求してみてください。

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

目次