見出し画像

画面キャプチャを利用してなるべく簡単に動画からの物体検出を実現させる方法

深層学習の分野では、動画解析のためにRNN(Recurrent Neural Networks)や3D CNN(3D Convolutional Neural Networks)、Optical Flowなどの複雑なモデルや手法が用いられることが多いです。特に、動画データは時間的な連続性を持っているため、フレーム間の関係を考慮に入れる必要があり、これには特別な前処理やモデルの設計が求められます。しかし、動画ファイルの読み込みや前処理、大量のフレームデータの管理など、時間がかかる作業が多く存在するため、深層学習とのインテグレーションには手間がかかります。そこで、今回紹介する方法では画面キャプチャを活用することで、これらの複雑な手続きを大幅に省略し、手軽かつ効率的に動画からの物体検出を実現します。


画面キャプチャを利用する利点

  • 手軽さ: 動画ファイルを直接プログラムに読み込む手間がありません。

  • 汎用性: YouTubeやNetflixなど、動画をローカルにダウンロードできない場合でもこの方法を適用できます。

  • シンプルなAIの利用: この手法は、キャプチャした「画像」に対して画像認識AIを適用するため、複雑な動画専用のAIではなく、比較的簡単に取り扱える画像処理用のAIを使用できます。

  • 自作モデルのテストが容易: 画面キャプチャを利用することで、自身で作成した画像認識モデルの性能を簡単に試すことができます。通常、モデルをテストする際には一枚一枚の画像をダウンロードして試す必要がありますが、この方法を使用すれば、画面に映すだけでモデルが正確に物体を認識できるかを確かめることができます。

動作環境

  • OS: この手法はWindows環境での動作をテストしています。そのため、Windows OS上での利用を推奨します。

  • Pythonライブラリ:

    • torchtorchvision: PyTorchフレームワークとその画像処理用のライブラリを使用しています。これにより、物体検出のためのモデルや画像の前処理を簡単に実装することができます。

    • PIL(Pillow): 画像の読み込みや表示、画像上に検出結果を描画するためのライブラリです。

    • screeninfo: 複数のディスプレイ環境において、特定のディスプレイの情報を取得するためのライブラリです。

  • ハードウェア:

    • GPUの利用は必須ではありませんが、NVIDIAのGPUを搭載した環境では、CUDAを利用して物体検出の計算を高速化することができます。特にリアルタイムでの動画解析を行う場合、GPUの利用は処理速度向上のために非常に推奨されます。

手順

必要なライブラリのインストール

pip install torch torchvision pyautogui screeninfo

ここでscreeninfoライブラリを使用するのは、複数のディスプレイ環境で正確に特定のディスプレイをキャプチャするためです。もし必要でなければ,プログラムの該当箇所を削除し,ライブラリもアンインストールしてください.

画面キャプチャの実装

動画解析の一般的な手法として、動画ファイルを直接読み込んでフレーム毎の画像データを取得する方法があります。しかし、この方法では動画の形式やエンコード方式に依存する問題や、特定の動画プレーヤーやプラットフォーム(例: YouTube, Netflix)で再生中の動画のデータを直接取得することが難しいといった課題があります。
画面キャプチャを利用することで、これらの課題を回避し、任意の画面上の映像データを直接キャプチャして物体検出の入力データとして使用することができます。これにより、様々な動画ソースから容易にデータを取得することが可能となります。
ここでは、具体的な画面キャプチャの方法と、複数のディスプレイが存在する場面で特定のディスプレイのみをターゲットとする方法を解説します。

from PIL import ImageGrab
from screeninfo import get_monitors

monitors = get_monitors()
display_index = 0  
selected_monitor = monitors[display_index]
screenshot = ImageGrab.grab(bbox=(selected_monitor.x, selected_monitor.y, selected_monitor.x + selected_monitor.width, selected_monitor.y + selected_monitor.height))

物体検出の実行

このセクションでは画面キャプチャで取得した映像データを物体検出モデルに入力し、リアルタイムで映像中の物体を検出するまでのプログラムを説明します。具体的には、キャプチャされた画像上に赤い枠で物体の位置が示され、その物体のカテゴリ(例: 人、車、犬など)がテキストで表示される形となります。このプロセスにより、ユーザはPCの画面上で動画や映像を再生しながら、どの部分にどのような物体が存在するのかをリアルタイムで確認することができます。

キャプチャした画像に対して、Faster R-CNNモデルを使用して物体検出を実行します。

# PIL画像をPyTorchテンソルに変換
image = torchvision.transforms.ToTensor()(screenshot).unsqueeze(0)

# 画像の正規化
image = F.normalize(image, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])

# 推論
with torch.no_grad():
    prediction = model(image)

結果の表示

キャプチャした画像に検出された物体の境界ボックスとラベルを表示します。

# 結果の表示
draw = ImageDraw.Draw(screenshot)
boxes = prediction[0]['boxes']
labels = prediction[0]['labels']
scores = prediction[0]['scores']

for box, label, score in zip(boxes, labels, scores):
    if score > 0.5:
        draw.rectangle([(box[0], box[1]), (box[2], box[3])], outline="red", width=2)
        draw.text((box[0], box[1]), str(label.item()), fill="red")

# キャプチャした画像を表示
screenshot.show()

完全なプログラム

以下は、すべてのステップを組み合わせた完全なプログラムです。

import torch
import torchvision
from torchvision.models.detection import fasterrcnn_resnet50_fpn
from torchvision.transforms import functional as F
from PIL import ImageGrab, ImageDraw
from screeninfo import get_monitors
import time

# モデルのロード
model = fasterrcnn_resnet50_fpn(pretrained=True)
model.eval()

monitors = get_monitors()
display_index = 0
selected_monitor = monitors[display_index]

while True:
    # 画面をキャプチャ
    screenshot = ImageGrab.grab(bbox=(selected_monitor.x, selected_monitor.y, selected_monitor.x + selected_monitor.width, selected_monitor.y + selected_monitor.height))

    # PIL画像をPyTorchテンソルに変換
    image = torchvision.transforms.ToTensor()(screenshot).unsqueeze(0)

    # 画像の正規化
    image = F.normalize(image, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])

    # 推論
    with torch.no_grad():
        prediction = model(image)

    # 結果の表示
    draw = ImageDraw.Draw(screenshot)
    boxes = prediction[0]['boxes']
    labels = prediction[0]['labels']
    scores = prediction[0]['scores']

    for box, label, score in zip(boxes, labels, scores):
        if score > 0.5:
            draw.rectangle([(box[0], box[1]), (box[2], box[3])], outline="red", width=2)
            draw.text((box[0], box[1]), str(label.item()), fill="red")

    # キャプチャした画像を表示
    screenshot.show()

    # 画像ウィンドウを閉じる
    for i in range(10):  # 10回試行してウィンドウを閉じる
        try:
            screenshot.close()
            break
        except:
            time.sleep(0.1)

    # 1秒待機
    time.sleep(1)

まとめ

画面キャプチャを活用した動画からの物体検出は、従来の動画解析手法と比べて手軽で効率的な方法と言えます。特に、動画コンテンツが豊富な現代において、このようなリアルタイムでの解析技術は非常に有用です。さらに、自身で開発した画像認識モデルのテストや、動画ストリーミングサービスでのコンテンツ分析など、さまざまなシーンでの利用が期待できます。


この記事が気に入ったらサポートをしてみませんか?