【体験談】roboflow/supervisionが私のCVプロジェクトを変えた話
こんにちは!今回は、コンピュータービジョンのプロジェクトに取り組むソフトウェアエンジニアの皆さんにとって、まさに「痒い所に手が届く」ツールであるroboflow/supervisionについて、その魅力と使い方をたっぷりご紹介します。
まるで、これまでバラバラだったパーツをピタッとつなぎ合わせてくれる接着剤のような存在で、開発効率がぐんとアップすること間違いなしですよ!
一言でいうと、roboflow/supervisionはコンピュータービジョン開発を強力にサポートするPythonライブラリです。特に、物体検出やセグメンテーションといったタスクにおいて、データの可視化、アノテーションの管理、モデルの評価など、様々な「かゆい所に手が届く」機能を提供してくれます。
「あ、これ、いつも手作業でやってた…」とか、「もっと簡単にできないかな?」と思っていた作業が、supervisionを使えばあっという間に片付くんです。まるで、優秀なアシスタントが一人増えたような感覚ですよ!
具体的に、私たちの開発現場でどのように役立つのか見ていきましょう。
煩雑な可視化作業からの解放
物体検出モデルの出力を、画像上にバウンディングボックスやセグメンテーションマスクとして描画する作業、地味に面倒ですよね。supervisionを使えば、数行のコードでプロフェッショナルな可視化が可能です。デバッグや結果の確認が劇的に楽になります!
データセットの準備・管理の効率化
機械学習モデルを訓練する上で、高品質なデータセットは不可欠です。supervisionは、アノテーションデータの読み込み、変換、フィルタリングなどをサポートし、データセットの準備・管理にかかる時間を大幅に削減します。
モデルの評価指標の算出が容易に
モデルの性能を評価する際に、mAP (mean Average Precision) などの指標を計算するのは意外と手間がかかります。supervisionには、これらの評価指標を簡単に算出するための機能が備わっており、モデルの改善サイクルを早めることができます。
トラッキング機能で動画解析もスムーズに
trackingというキーワードにもあるように、動画中の物体の動きを追跡するトラッキング機能も充実しています。防犯カメラの映像解析や、スポーツの動きの分析など、動的なシーンでの活用に非常に便利です。
学習コストが低い!
Pythonに慣れている方なら、直感的に使えるシンプルなAPI設計が魅力です。複雑な設定は不要で、すぐに使い始めることができます。
導入はとても簡単です!Pythonのパッケージマネージャーであるpipを使ってインストールするだけです。
pip install supervision
たったこれだけ!これで、あなたのPython環境にsupervisionが使えるようになります。
実際に使ってみると、その便利さがよくわかります。ここでは、最も基本的な「画像にバウンディングボックスを描画する」例と、「物体をトラッキングする」例をご紹介します。
import cv2
import supervision as sv
import numpy as np
# ダミーの画像と物体検出結果を準備
# 実際のプロジェクトでは、ここにあなたの画像とモデルの予測結果が入ります
image = cv2.imread("your_image.jpg") # 実際の画像パスに置き換えてください
if image is None:
print("画像を読み込めませんでした。your_image.jpg が存在するか確認してください。")
# 代わりに白いダミー画像を生成
image = np.ones((480, 640, 3), dtype=np.uint8) * 255
print("ダミー画像で続行します。")
# ダミーの検出結果 (例: 物体A, 物体B)
# バウンディングボックスの形式は [x_min, y_min, x_max, y_max]
detections = sv.Detections(
xyxy=np.array([
[100, 100, 200, 200], # 物体A
[300, 250, 450, 400] # 物体B
]),
class_id=np.array([0, 1]), # クラスID (例: 0=人, 1=車)
confidence=np.array([0.9, 0.8]) # 信頼度
)
# クラス名 (あなたのモデルのクラス名に合わせてください)
class_names = ["person", "car"]
# BoundingBoxAnnotator を初期化
box_annotator = sv.BoundingBoxAnnotator()
label_annotator = sv.LabelAnnotator(text_scale=0.7, text_thickness=1, text_color=sv.Color.white(), text_padding=sv.Point(10, 10))
# 画像にバウンディングボックスとラベルを描画
annotated_image = box_annotator.annotate(scene=image.copy(), detections=detections)
annotated_image = label_annotator.annotate(
scene=annotated_image, detections=detections, labels=[
f"{class_names[class_id]} {confidence:.2f}"
for class_id, confidence in zip(detections.class_id, detections.confidence)
]
)
# 結果を表示
cv2.imshow("Annotated Image", annotated_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
このコードでは、sv.Detectionsで検出結果を定義し、sv.BoundingBoxAnnotatorとsv.LabelAnnotatorを使って簡単にバウンディングボックスとラベルを描画しています。これだけで、モデルの出力が視覚的にわかりやすくなりますよね!
import cv2
import supervision as sv
import numpy as np
# ダミーの動画ファイル(例: video.mp4)を準備してください
# 実際のプロジェクトでは、ここにあなたの動画パスが入ります
video_path = "your_video.mp4"
# デモンストレーション用にダミーのビデオライターを作成(実際の動画ファイルがない場合)
try:
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise FileNotFoundError
except FileNotFoundError:
print(f"警告: {video_path} が見つかりませんでした。ダミーの動画を生成します。")
# ダミーの動画を生成するコード
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
dummy_video_path = "dummy_video.mp4"
out = cv2.VideoWriter(dummy_video_path, fourcc, 20.0, (640, 480))
for i in range(100): # 100フレームのダミー動画
frame = np.ones((480, 640, 3), dtype=np.uint8) * 255
# フレームごとに動くダミーの矩形を描画
x_pos = (i * 5) % 500
cv2.rectangle(frame, (x_pos, 200), (x_pos + 50, 250), (0, 255, 0), -1)
out.write(frame)
out.release()
print(f"ダミー動画を {dummy_video_path} に保存しました。")
video_path = dummy_video_path
cap = cv2.VideoCapture(video_path)
# BoundingBoxAnnotator と TraceAnnotator を初期化
box_annotator = sv.BoundingBoxAnnotator()
trace_annotator = sv.TraceAnnotator(
color=sv.Color.white(),
thickness=2,
trace_length=50
)
label_annotator = sv.LabelAnnotator(text_scale=0.7, text_thickness=1, text_color=sv.Color.white(), text_padding=sv.Point(10, 10))
# ByteTrackを例にトラッカーを初期化
# 実際のプロジェクトでは、ご自身のモデルと組み合わせてください
tracker = sv.ByteTrack(frame_rate=30) # フレームレートは動画に合わせてください
# 動画を読み込み、フレームごとに処理
while True:
ret, frame = cap.read()
if not ret:
break
# ここにあなたの物体検出モデルの予測結果を挿入します
# 例として、ここではダミーの検出結果を生成します
# 実際の検出結果は detections = your_model.predict(frame) のようになるでしょう
dummy_detections = sv.Detections(
xyxy=np.array([
[100 + (cap.get(cv2.CAP_PROP_POS_FRAMES) * 2) % 400,
100,
200 + (cap.get(cv2.CAP_PROP_POS_FRAMES) * 2) % 400,
200]
]),
class_id=np.array([0]),
confidence=np.array([0.9])
)
# トラッカーに検出結果を渡す
detections = tracker.update_with_detections(dummy_detections)
# アノテーション
annotated_frame = box_annotator.annotate(scene=frame.copy(), detections=detections)
annotated_frame = trace_annotator.annotate(scene=annotated_frame, detections=detections)
annotated_frame = label_annotator.annotate(
scene=annotated_frame, detections=detections, labels=[
f"ID: {track_id}"
for track_id in detections.tracker_id
]
)
cv2.imshow("Tracked Video", annotated_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
このサンプルでは、sv.ByteTrack(一般的なトラッカーの一つ)を使って、動画中の物体の動きを追跡しています。TraceAnnotatorを使うことで、物体の軌跡を視覚的に表示できるのが面白いですね。もちろん、ここにあなたの高性能な物体検出モデルの出力を組み合わせることで、より実用的なトラッキングシステムを構築できます。
roboflow/supervisionは、コンピュータービジョンの開発プロセスをシンプルにし、効率を飛躍的に向上させてくれる強力なツールです。データの可視化からモデルの評価、さらにはトラッキングまで、幅広い機能が提供されています。
特に、私たちソフトウェアエンジニアにとっては、これまで手作業で行っていた煩雑な作業を自動化し、より本質的な問題解決に集中できる時間を与えてくれる、まさに「開発者のための開発ツール」と言えるでしょう。
ぜひあなたの次のコンピュータービジョンプロジェクトで、roboflow/supervisionを試してみてください。きっと、その手軽さと強力さに驚くはずですよ!