mcpField
U
UVC PTZ Camera

UVC PTZ Camera

ローカル
github.comメディア・デザイン03 週間前に更新

UVC PTZ Camera について

UVC PTZ Cameraは、USB UVCのパン・チルト・ズームカメラ向けMCPサーバーです。向きやズームを操作でき、デバイスの位置報告に頼らず、操作前後の画像を比較して移動を確認します。

主な機能

  1. 01カメラ、軸、可動範囲の確認
  2. 02角度指定と相対的な微調整
  3. 03スムーズなスイープとズーム
  4. 04画像比較による移動確認
  5. 05ショット手順の計画と実行
  6. 06顔検出による人物追跡

活用シーン

  1. 01カメラを指定した方向へ向ける
  2. 02パノラマ撮影後のズームを計画する
  3. 03操作で映像が変化したか確認する
  4. 04顔検出で人物を追跡する

MCP 対応

MCPサーバーは、状態確認、照準、微調整、スイープ、ズーム、映像確認、ショット計画のツールを公開します。画像を比較して移動を確認し、デバイスの位置報告は参考値として返します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"abhijatsaxena-uvc-ptz-camera": {
"command": "uvx",
"args": [
"uvc-ptz-camera-mcp"
],
"env": {
"UVC_PTZ_STATE_DIR": "<UVC_PTZ_STATE_DIR>",
"UVC_PTZ_SIM_SOURCE": "<UVC_PTZ_SIM_SOURCE>"
}
}
}
}
起動コマンドuvx uvc-ptz-camera-mcp
設定が必要な環境変数
UVC_PTZ_STATE_DIRWhere to store what has been learned about each camera. Defaults to ~/.uvc-ptz-camera-mcp. Holds angles, never credentials.
UVC_PTZ_SIM_SOURCEPath to an image to use as the simulator's panorama instead of the synthesised one.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypiuvc-ptz-camera-mcp0.2.0

ツール

17

掲載時のツール一覧 · 2 週間前に更新

このツールにパラメーターはありません。

詳細

uvc-ptz-camera-mcp

python license

USB(UVC)パン/チルト/ズームカメラ用のMCPサーバーです。カメラの向きを変えたり、少し動かしたり、滑らかに旋回させたり、ズームしたり、映像を確認したりできます。すべての動作は、前後の映像を比較して確認します。

アカウントもクラウドも、ベンダーの SDK も不要です。デバイス 1 台と USB ケーブル 1 本だけです。

camera_status       the camera, its axes and ranges, and whether it is real
aim                 point an axis at an absolute value, confirmed from the picture
nudge               move relative to where the device says it is
sweep               a smooth timed move, streamed at 15 Hz
zoom                set zoom as a multiplier (1x .. the camera's maximum)
recentre            every axis back to its default
look                one frame, returned as an image
aim_learn           remember "this direction is the desk"
aim_list            what has been recorded for this camera
go_to               point at a recorded direction
plan_shot           compile a multi-step shot and report what it would do, moving nothing
run_shot            execute a multi-step move, verified after every waypoint
mark_view           store the current picture under a label
check_view          has the picture changed since that label?
track_start         follow a subject: detect, measure, take a step, look again
track_status        what the follow loop is doing, iteration by iteration
track_stop          stop following and report what it saw and what it moved

撮影の構成は、plan_shot に続けて run_shot を実行します。計画では、実行時にコンパイルされるものとまったく同じ手順をコンパイルし、手順ごとのスケジュール、各軸の移動距離、所要時間を報告します。また、デバイスには一切触れません。これにより、エージェントは何かを動かす前に、カメラの実際の範囲を使って「パノラマを撮ってから、自分にズームインする」といった内容を調整できます。動かした後で初めて問題に気づくことはありません。

追従

track_start は、カメラを被写体に向け続けるループを実行します。被写体を検出し、フレーム中央からの距離を測定し、制限付きで動かしてから、もう一度確認します。ほかの動作と同じ理由で、判断には映像だけを使います。このカメラが報告する向きは信頼できないためです。被写体を見失ったとき、デッドゾーン内で安定したとき、カメラが応答しなくなったとき、または max_seconds に達したときに、自動的に停止します。track_status には、測定したオフセットと適用した移動量を含め、各反復の結果がすべて記録されます。

2 つの値はデバイスではなく マウント に依存するため、推測で決めず明示的なパラメーターにしています。オフセット 1 ピクセルあたりの移動角度を指定する gain と、方向を反転する invert です。設定を誤ると、残差が増えていく様子にそのまま表れます。また、1 回の反復での移動量は 25 度までに制限されるため、gain が誤っていても、1 回のコマンドでカメラが全範囲を横切ることはなく、ゆっくりと収束します。

検出には OpenCV に同梱されている顔カスケードを使います(pip install 'uvc-ptz-camera-mcp[tracking]')。初回使用時にモデルのダウンロード、アカウント、ネットワークは必要ありません。検出対象は顔です。そのため、人には追従しますが、車や犬には追従しません。ループとその計算はシミュレーターでテストされていますが、追従モードが実機で動作したことは一度もありません。ここで最も検証が不十分な機能として扱ってください。

このプロジェクトの目的

この種のカメラは、実際には移動していない位置を報告します。基準デバイス(標準の UVC コントロールを使ったウェブカメラモードの DJI Osmo Pocket 4P)で測定した結果は次のとおりです。

  • パンを 180 にするコマンドでは、映像上はカメラがまったく動いていないにもかかわらず、読み戻し値は 180 でした。
  • 32 秒間の実行全体で、フレームが明らかに変化していたにもかかわらず、すべてのサンプルで読み戻し値は 0 でした。
  • パンを 120 にすると読み戻し値は 119、パンを 200 にすると読み戻し値は 199 でした。

エージェントがこれらの値をもとに動作すると、実際には起きていない移動を報告してしまいます。そのため、このサーバーではデバイスが報告する値をすべて参考値として扱います。値は返してラベルを付けますが、信頼はせず、フレームを比較して moved を判定します。

しきい値も推測ではありません。ラベル付きの実機フレームを使って調整しました。「同じ映像」の各ペアはすべて ≤ 0.104(96 秒間の静止ベースラインと、ハードウェアが無視した 2 つのコマンド)、「映像が変化した」各ペアはすべて ≥ 0.624(パン、チルト、12 倍ズーム、2 回の向き調整)でした。採用しているしきい値はその中間の 0.364 で、両者には 6 倍の差があります。テストスイートでは、現在もこのしきい値で両者を区別できることを検証しています。ラベル付きのペアとメトリクスが出した値は、信じるだけでなく再確認できるよう、リポジトリのtests/fixtures/に保存しています。これは画像ではなく測定値です。カメラで撮影したフレームや動画はリポジトリにコミットされておらず、もし含まれていればテストは失敗します。調整の根拠となった測定結果はdocs/measurements.mdに記載されています。

エージェントの動作を正直に保つ仕組み

  • moved は画像から判定されます。 device_reported はヒントとしてラベル付けされ、moved と一緒に返されます。
  • 変化のなかった移動は、何も知らせずに成功とするのではなくエラーになります — 回数を制限して再試行した後、要求された内容と観測された内容を示してツールが失敗します。
  • すでに目標位置にいる場合は、移動なしで成功します:moved: false となり、エラーは発生しません。
  • ブロッキング処理がイベントループ上で実行されることはありません(COM 呼び出し、ffmpeg によるキャプチャ)。カメラにアクセスしたスレッドを記録するテストで確認されています。
  • 観測は明示的に行われます:呼び出したツール以外が画像を撮ることはありません。
  • 書き込みが拒否された場合は撮影を中止します。応答しなくなったカメラを動かし続けることはありません。

インストール

uvx uvc-ptz-camera-mcp            # run without installing
pip install uvc-ptz-camera-mcp    # or install it

Windows で実際のカメラを使う場合は、DirectShow の追加コンポーネントも必要です。

pip install "uvc-ptz-camera-mcp[dshow]"

次にホストからこのサーバーを指定します — --print-config を実行すると、適切なインタープリターを使った設定例が出力されます。

uvc-ptz-mcp --print-config
uvc-ptz-mcp --list-devices        # what to pass to --device
uvc-ptz-mcp --backend simulator   # try it with no camera attached
設定の追加先

Claude Desktop、Cursor、VS Code などでは、同じ形式の設定を使用します — 認証が不要なため、設定全体は次のとおりです。

{
  "mcpServers": {
    "ptz-camera": {
      "command": "uvx",
      "args": ["uvc-ptz-camera-mcp"]
    }
  }
}

カメラが複数ある場合は、--device, "Osmo"(--list-devices が出力する名前の一部であれば指定できます)を追加します。カメラがない状態で使う場合は、"--backend", "simulator" を追加します。どちらも引数の代わりに環境変数 UVC_PTZ_DEVICE、UVC_PTZ_BACKEND、UVC_PTZ_STATE_DIR で設定できます。Claude Desktop バンドルではこの方法が使われており、ホストを再起動しても設定を編集し直す必要はありません。フラグは環境変数より優先されます。また、空の値は「未設定」を意味します(オプションを空欄のままにするホストは、何も書き込まずに "" を書き込みます)。Claude Desktop では、各リリースに添付された .mcpb バンドルを使って、ワンクリックでインストールすることもできます。

モードと、使用中のモードの確認方法

バックエンド説明
auto(デフォルト)実際のカメラを優先し、使えない場合は理由を示してシミュレーターに切り替えます
dshowWindows DirectShow:実際のデバイスを使うモードです
simulatorハードウェアを一切使わず、以下の測定値に基づいて調整されたモデルを使います

すべての結果には "simulated": true または false が含まれ、シミュレーターが代替として使われている場合は camera_status にその理由が報告されます。ハードウェアであるかのようにひそかに装うことはありません。モデルを操作しているのにカメラを操作していると、呼び出し元が誤認することがあってはなりません。

シミュレーターは基準デバイスの測定値に基づいて調整されたものであり、作り上げたものではありません:書き込みから最初の動きまで約 0.4 秒、パンの完了まで約 1 秒、4 倍ズームまで約 2.5 秒、書き込みがひそかに破棄されること、そしてハードウェアが適用しなかった要求を読み戻し結果がそのまま返すこと。フレームは広角パノラマを切り取って描画するため、シミュレーターでパンするとピクセルも実際に変化します。静止画を使うシミュレーターでは、検証が実質的に何も確認せず通過してしまいます。

正直な制限事項

  • 実機を使う経路は Windows 専用です(DirectShow)。Linux バックエンドでは v4l2 を使用します。インターフェースは用意されていますが、実装はまだありません。
  • 露出、フォーカス、ホワイトバランスには対応していません。 リファレンスカメラには Processing Unit がまったくなく、パン/チルト/ロール/ズームのみを備えています。
  • ベンダーの Extension Unit は Windows から到達できません。そのため、そこにある機能(リファレンスカメラでは内蔵の被写体トラッキング)をソフトウェアから操作できません。実測では、デバイスフィルター上の IKsControl は拒否され、IKsTopologyInfo はベンダーノードなしで3つのノードを列挙し、すべてのノードで CreateNodeInstance が失敗します。Linux では uvcvideo の UVCIOC_CTRL_QUERY を通じてアクセスできますが、これは別のバックエンドです。
  • 被写体が動くと、カメラが動いたように見えます。 フレーム比較では両者を区別できません。静止したシーンで適切に動作するようメトリクスを調整しており、check_view は移動ではなく視点を評価するためのものです。
  • 使用できないデバイスが、ほかのデバイスを隠してはいけません。 登録されているものの利用できない仮想カメラは、DirectShow モニカーのバインド時に例外を発生させ、本来なら動作するカメラを2台返すはずの一覧表示を中断していました。現在、列挙処理では読み込めないデバイスをスキップして、その旨を通知します。同じルールは、指定されたカメラを探すバックエンド内にも適用されます。
  • 実測レイテンシが上限を決めます。コマンドから動作まで約0.4秒かかるため、制御ループは数十Hzではなく、数Hzで動作します。これはハードウェアが原因であり、ソフトウェアが原因ではありません。
  • DirectShow 経路はテスト済みですが、まだ実運用されていません。 開発途中でリファレンスデバイスが返却されたため、ハードウェア経路はインターフェースまで検証され、型も正しく定義されていますが、テストの大部分はシミュレーターが担っています。実カメラでの初回実行を、実際の受け入れテストとして扱ってください。

開発

pip install -e ".[dshow]" numpy pytest pytest-asyncio ruff
python -m pytest -q                     # 39 tests, three layers
python -m ruff check . && python -m ruff format --check .

テストスイートは意図的に複数の層に分かれています。マッピング、検証、適切なエラー処理についてはシミュレーターを使ったプロセス内のツールテストを行い、コンパイラーとメトリクスについては純粋な単体テストを行います。また、サブプロセスとして実際の stdio ハンドシェイクもテストします。その中には、存在し得ないデバイス名を指定して実行するテストも含まれています。起動時に終了するサーバーは、それを一覧表示するすべてのホストやディレクトリから見えないためです。

リファレンスデバイス

ウェブカメラモードの DJI Osmo Pocket 4P を使用して開発しています。標準の UVC カメラコントロールとして、VID_2CA3/PID_0023 がパン −38…215°、チルト −33…105°、ロール ±35°、ズーム 100…1200(1×–12×)を公開します。UVC PTZ カメラなら、どれも同じインターフェースを公開します。範囲は想定値ではなく起動時にデバイスから読み取り、ベンダー固有の値はハードコードしていません。

DJI とは提携関係になく、DJI による推奨やサポートも受けていません。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。