ORB特徴点検出カメラキャプチャプログラム

目次

1. 概要

主要技術:ORB(Oriented FAST and Rotated BRIEF)特徴点検出

プログラム概要
Webカメラからリアルタイム映像を取得し、ORB特徴点検出により画像間の重なり面積を自動計算、設定した閾値(80%)以下になった時点で新しい視点のフレームとして自動保存するカメラキャプチャプログラ

技術の論文

技術の新規性・特徴
ORBは従来のSIFT・SURFと比較して高速な特徴点検出・記述子計算を実現する。FAST(Features from Accelerated Segment Test)はコーナー検出に特化したアルゴリズムであり、BRIEF(Binary Robust Independent Elementary Features)はバイナリ形式(0と1)で特徴を表現するため計算量が少ない。従来手法が浮動小数点記述子を使用するのに対し、ORBはハミング距離によるマッチングを可能にする。

活用可能なアプリケーション例
リアルタイム物体認識、SLAM(Simultaneous Localization and Mapping)、AR(拡張現実)、画像マッチング、カメラトラッキング

技術的制約
テクスチャの少ない平面では特徴点検出が困難である。照明変化や視点変化に対する耐性に限界がある。リアルタイム処理と精度にはトレードオフ関係が存在する。

体験価値
リアルタイムカメラ映像から特徴点を自動検出し、重なり面積に基づいて新しい視点のフレームを自動保存するプログラムを確認

2. 事前準備

Python, Windsurfをインストールしていない場合の手順(インストール済みの場合は実行不要)。

  1. 管理者権限でコマンドプロンプトを起動する(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」)
  2. 以下のコマンドをそれぞれ実行する(wingetコマンドは1つずつ実行)
REM Python をシステム領域にインストール
winget install --scope machine --id Python.Python.3.12 -e --silent
REM Windsurf をシステム領域にインストール
winget install --scope machine --id Codeium.Windsurf -e --silent
REM Python のパス設定
set "PYTHON_PATH=C:\Program Files\Python312"
set "PYTHON_SCRIPTS_PATH=C:\Program Files\Python312\Scripts"
echo "%PATH%" | find /i "%PYTHON_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_PATH%" /M >nul
echo "%PATH%" | find /i "%PYTHON_SCRIPTS_PATH%" >nul
if errorlevel 1 setx PATH "%PATH%;%PYTHON_SCRIPTS_PATH%" /M >nul
REM Windsurf のパス設定
set "WINDSURF_PATH=C:\Program Files\Windsurf"
if exist "%WINDSURF_PATH%" (
    echo "%PATH%" | find /i "%WINDSURF_PATH%" >nul
    if errorlevel 1 setx PATH "%PATH%;%WINDSURF_PATH%" /M >nul
)

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

コマンドプロンプトを管理者として実行(手順:Windowsキーまたはスタートメニュー > cmd と入力 > 右クリック > 「管理者として実行」)し、以下を実行する

pip install opencv-python numpy

3. 動作原理

基本概念
特徴点とは画像内の特徴的な点(コーナー、エッジ等)である。記述子は特徴点周辺の画像パターンを数値化した情報であり、マッチングは異なる画像間で対応する特徴点を見つける処理である。

処理手順
ORBは特徴点を検出し記述子を計算、マッチングを行う。ホモグラフィ行列(画像間の幾何学的変換を表す行列)で画像変換を計算し、グリッドベースで重なり面積を算出する。重なり面積が閾値以下の場合に新しい視点として判断する。

4. プログラムコード

# ORB特徴点検出カメラキャプチャプログラム
# Webカメラから重なり面積が閾値以下のフレームを自動保存
# 論文: Rublee, E., Rabaud, V., Konolige, K., & Bradski, G. (2011). ORB: An efficient alternative to SIFT or SURF. ICCV 2011.
# GitHub: https://github.com/opencv/opencv
# 特徴: ORBは高速な特徴点検出・記述子計算手法、リアルタイム処理対応
#       FAST+BRIEF組み合わせによる高速性、バイナリ記述子による効率性
# 学習済モデル: 使用なし(手作りアルゴリズム)
# 前準備: pip install opencv-python numpy (管理者権限のコマンドプロンプトで実行)
import cv2
import numpy as np

# 定数定義
OVERLAP_THRESHOLD = 0.8
GRID_SIZE = 10
HOMOGRAPHY_RANSAC_THRESHOLD = 5.0

# カメラ初期化(DirectShowバックエンド使用)
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)

if not cap.isOpened():
    print("エラー: カメラを開けません")
    exit()

# 変数初期化
frame_count = 0
ref_frame = None
ref_kp = None
ref_desc = None
orb = cv2.ORB_create()

print("カメラ開始。'q'で終了。重なり面積80%以下で保存。")

# メイン処理
while True:
    # バッファをクリア(最新フレームのみ取得)
    cap.grab()
    ret, frame = cap.retrieve()
    if not ret:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 初回フレーム処理
    if ref_frame is None:
        ref_frame = gray.copy()
        ref_kp, ref_desc = orb.detectAndCompute(ref_frame, None)

        if ref_desc is not None:
            cv2.imwrite(f"frame_{frame_count:03d}.jpg", frame)
            print(f"基準フレーム保存: frame_{frame_count:03d}.jpg")
            frame_count += 1
    else:
        # 特徴点抽出とマッチング
        curr_kp, curr_desc = orb.detectAndCompute(gray, None)

        if (curr_desc is not None and ref_desc is not None and
            len(ref_desc) >= 4 and len(curr_desc) >= 4):

            bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
            matches = bf.match(ref_desc, curr_desc)

            if len(matches) >= 4:
                # ホモグラフィ計算
                ref_pts = np.float32([ref_kp[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
                curr_pts = np.float32([curr_kp[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)

                H, _ = cv2.findHomography(curr_pts, ref_pts, cv2.RANSAC, HOMOGRAPHY_RANSAC_THRESHOLD)

                if H is not None:
                    h, w = gray.shape
                    corners = np.float32([[0,0], [w,0], [w,h], [0,h]]).reshape(-1, 1, 2)
                    ref_corners = cv2.perspectiveTransform(corners, H)

                    # 重なり面積計算(calc_overlap関数を直接埋め込み)
                    total = 0
                    inside = 0
                    for x in range(0, w, GRID_SIZE):
                        for y in range(0, h, GRID_SIZE):
                            total += 1
                            if cv2.pointPolygonTest(ref_corners, (x, y), False) >= 0:
                                inside += 1
                    overlap = inside / total

                    if overlap < OVERLAP_THRESHOLD:
                        cv2.imwrite(f"frame_{frame_count:03d}.jpg", frame)
                        print(f"保存: frame_{frame_count:03d}.jpg (重なり: {overlap:.2%})")
                        frame_count += 1

                        # 基準更新
                        ref_frame = gray.copy()
                        ref_kp, ref_desc = orb.detectAndCompute(ref_frame, None)

    cv2.imshow('Camera', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 結果出力
cap.release()
cv2.destroyAllWindows()
print(f"終了。保存フレーム数: {frame_count}")

5. 使用方法

実行手順

  1. 上記のプログラムを実行する
操作方法

出力結果

6. 実験・探求のアイデア

AIモデル選択の実験

ORB以外の特徴点検出手法との比較を行う。代表的な手法にはSIFT、SURF、AKAZE、BRISKがある。各手法の検出速度、検出精度、マッチング精度を比較し、手法間の性能差と適用場面の違いを理解する。

実験要素の調整

  1. 閾値パラメータの調整
    • OVERLAP_THRESHOLDを0.5、0.7、0.9に変更して保存頻度の変化を観察(閾値と保存タイミングの関係を理解)
    • GRID_SIZEを5、15、20に変更して計算精度と速度の関係を確認(精度と処理速度のトレードオフを学習)
  2. ORBパラメータの調整
    • nfeatures(特徴点数)を500、1000、2000に変更して検出性能を比較(特徴点数と認識精度の関係を分析)
    • scaleFactor(スケール係数)を1.1、1.3、1.5に変更してマルチスケール性能を確認(スケール変化への対応能力を評価)