1.ONVIFカメラ

更新日: 2026.10.26

概要

”ONVIF"対応の市販ネットカメラはPythonで簡単に制御出来ます。 市販のネットカメラには専用のアプリが有りますが、自分でアプリを作るのも楽しいものです。

"ONVIF"と対応カメラメーカ

  • ONVIF(Open Network Video Interface Forum)
    • ネットワークカメラ等のIPセキュリティ機器において異なるメーカー製品同士でも互換性を保ち連携できるようにするための標準規格。
    • 専用のライブラリを使用してカメラへの接続を確立し、カメラが持つ機能(映像配信やPTZ制御など)へのアクセス窓口として利用される。
  • 対応している主なメーカー
    • TP-Link(ティーピーリンク)、Reolink(リオリン)、Panasonic など
    • TP-Link社の ”TAPOカメラ” がお薦め。
    • 安価なIoTカメラ(中国製等の一部モデル)の場合、初期状態ではセキュリティや専用アプリ縛りのためONVIFが無効化されていることが多い。

準備

カメラ側

今回はTAPOカメラ "C200" と "C520SW" を使って見ました。まずは専用のアプリ(スマホ用)でカメラをセットアップします。

TAPO Camera & its Apri
  • 使用したネットカメラ
    • "C200"
      • 室内用カメラ。パン、チルト、ズーム機能を持つ。
      • その他:夜間撮影(多分赤外線撮影)
    • "C520SW"
      • 屋外用カメラ。パン、チルト、ズーム機能を持つ。
      • その他:夜間撮影(多分赤外線撮影)、ライト点灯機能
  • スマホにTP-Link Tapoをインストール
    • メーカ専用アプリをスマホにインストール。
    • アカウントの登録やカメラのWiFiへの接続等行って下さい。
  • インストールが完了するとスマホにアプリのアイコンが出来ます。

次に "ONVIF" 用の設定を行います。

TAPO Camera set up for ONVIF
  • アプリで対象のカメラを選び、”デバイス設定”に入る。
  • そこにある "高度な設定”をクリック
  • "高度な設定”画面で "カメラのアカウント"、"ネットワーク設定"を行います。
    • "ネットワーク設定"
      • ONVIFはカメラのIPアドレスを使用する。取り扱いを考慮しIPアドレスを固定。
      • 上部の "静的IP" をオンにし、IPアドレス、マスク、ゲートウェイ、DNSを入力。
      • 最後に "保存" ボタンを押して終了。
    • "カメラのアカウント"
      • これもONVIFで必要です。上部の "カメラのアカウント"ボタンをオンにして
      • "ユーザー名"、"パスワード"を入力して設定します。

サーバー側

サーバとして Raspberry PI 3B を使用します。

  • Raspberry PI Imager(V1.8.5)で "Legacy,64-bit Lite (Bookworm no desktop)" をインストール
  • インストール後、ホームディレクトリで下記を実行
      sudo apt update sudo apt full-upgrade -y sudo apt install -y python3-flask python3-pip python3-opencv python3-numpy python3-requests ffmpeg pip install onvif-zeep --break-system-packages

カメラ制御用コード

カメラとの接続

"ONVIF" インスタンスと各種サービスを作成。

  • "ONVIF" インスタンス作成。
    • mycam = ONVIFCamera(target_ip, target_port, target_user, target_pass, wsdl_dir='xxxxx')
      • target_ip:TAPOアプリで固定設定したIPアドレス。
      • target_port:TAPOの場合は2020。
      • target_user:TAPOアプリで設定したユーザー。
      • target_pass:TAPOアプリで設定したパスワード。
      • wsdl_dir='xxxxx':WSDLファイルのパス。
        • 今回のインストールでは "/home/xxxx/.local/lib/python3.4/site-packages/wsdl" となる。
          (注:xxxxはユーザ名)
  • メディアサービス (media): 映像の配信設定やストリーミングURIを取得するために使用。
    • media = mycam.create_media_service()
    • これを元にプロファイルの取得とトークンの特定
      • profiles = media.GetProfiles()
      • token = profiles[0].token if profiles else 'profile_1'
  • PTZサービス (ptz): カメラの向き(パン・チルト・ズーム)を制御するために使用。
    • ptz = mycam.create_ptz_service()
  • 接続の確認
    • 下記のコード "connect.py" を実行して下さい。各接続が確認出来ます。
    • from onvif import ONVIFCamera target_ip = "xxx.xxx.xxx.xxx" # カメラのIPアドレス target_port = 2020 # カメラのポート(TAPOは2020) target_user = "user name" # カメラのユーザー名 target_pass = "password" # カメラのパスワード try: mycam = ONVIFCamera( target_ip, target_port, target_user, target_pass, wsdl_dir='/home/xxxx/.local/lib/python3.4/site-packages/wsdl' # xxxxはユーザ ) ptz = mycam.create_ptz_service() media = mycam.create_media_service() profiles = media.GetProfiles() token = profiles[0].token if profiles else 'profile_1' print(f"ネットカメラ接続完了") except Exception as e: print(f"ネットカメラ接続失敗 ({target_ip}): {e}")
    • モニタで "python3 connect.py" を実行して "ネットカメラ接続完了" が表示されれば接続OKです。

カメラから静止画とStreamingを取得

カメラから静止画とStreamingのURLを取得します。"python3 connect.py" コードに下記を追加。

# 静止画の取得 try: snapshot_uri_obj = media.GetSnapshotUri({'ProfileToken': token}) print(f"静止画URL取得完了") except Exception as e: print(f"静止画取得 Error: {e}") # 動画の取得 try: stream_setup = {'Stream': 'RTP-Unicast', 'Transport': {'Protocol': 'TCP'}} uri_obj = media.GetStreamUri({'StreamSetup': stream_setup, 'ProfileToken': token}) print(f"動画RTSP URL取得完了") except Exception as e: print(f"動画取得 Error: {e}")

これを "connect_pic.py" と保存してモニタで実行すると

    ~/net-camera $ python3 connect_pic.py ネットカメラ接続完了 静止画取得 Error: Unknown error: 動画RTSP URL取得完了

静止画がエラーになりました。"ONVIF" 規格に静止画もあるのですが、このモデルの様に対応していないモデルが多いようです。

Streamingは対応していますが規格が "RTSP"。そのままではブラウザの画面に表示出来ません。 "OpenCV" を使ってブラウザに有った形式に変換する必要が有ります。

そこで今回は"OpenCV" とStreamingを使って先ず静止画を作成。Streamingは静止画を随時送る方法(MJPEG)で対応する事にしました。 下記はStreaming(RTSP)から静止画(jpg)を1画面取得するサンプルコードです。

sample.py python
import cv2 cap = None try: stream_setup = {'Stream': 'RTP-Unicast', 'Transport': {'Protocol': 'TCP'}} uri_obj = media.GetStreamUri({'StreamSetup': stream_setup, 'ProfileToken': token}) print("動画RTSP URL取得完了") rtsp_uri = uri_obj.Uri protocol, rest = rtsp_uri.split('://', 1) rtsp_uri = f"{protocol}://{username}:{password}@{rest}" cap = cv2.VideoCapture(rtsp_uri, cv2.CAP_FFMPEG) # フレーム取得 ret, frame = cap.read() # フレームをjpgに変換 success, encoded_image = cv2.imencode(".jpg", frame) print("静止画(jpg)の取得に成功しました!") except Exception as e: print(f"Background camera error: {e}") finally: if cap is not None: cap.release() print("カメラリソースを解放しました")
  • 7行:Pythonが ONVIF に動画のURL "RTSP" を要求。
  • 13行:取得した "RTSP" を OpenCV 用に形式を変換。
  • 15行:変換された"URL"を用いてOpenCVで"RTSP"をライブ映像として読み込む為のオブジェクトを作成。
  • 18行:1画面を取得。データ型はNumPyの多次元配列。ブラウザに表示出来ない。
  • 21行:形式を "jpg" に変換。これでブラウザに表示出来る。

静止画、Streamingをブラウザに表示するアプリ

ブラウザに静止画、Streamingを表示するアプリを製作します。まずRaspberry PI のホームで下記を実行。

~ $ wget https://hp.hatakekara.com/contents/raspberry/project/net-camera/img/net-camera.zip ~ $ sudo apt install -y unzip ~ $ unzip net-camera.zip

実行後、ホームの下に "net-camera" フォルダーが下記の様に製作されます。

net-camera ├── net-camera.py ├── static │   └── favicon.ico └── templates └── index.html

フォルダ "net-camera" に移動(cd net-camera)して "net-camera.py" を修正。修正箇所は
wsdl_dir='/home/xxxx/.local/lib/python3.4/site-packages/wsdl' の "xxxx" をユーザー名に変更

net-camera.py python
try: mycam = ONVIFCamera( target_ip, target_port, target_user, target_pass, wsdl_dir='/home/xxxx/.local/lib/python3.4/site-packages/wsdl' # xxxxはユーザー名 ) ptz = mycam.create_ptz_service() media = mycam.create_media_service() profiles = media.GetProfiles() token = profiles[0].token if profiles else 'profile_1'

その後 python3 net-camera.py で実行。

~/net-camera $ python3 net-camera.py * Serving Flask app 'net-camera' * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://xxx.xxx.xxx.xxx:5000 Press CTRL+C to quit
 モニタに上記が表示されたらブラウザを上げて、"http://bbb.local:5000" (注:bbbはホスト名)と入力して下さい。 下記のHPが表示されます。

HP of Net Camera Control

使い方

  • 最初にカメラと接続
    • 必要項目を入力
      • IP: カメラのIPアドレス
      • Port: カメラのポート(TAPOは2020)
      • User: カメラのユーザー名
      • Pass: カメラのパスワード
    • 入力後、”接続” ボタンを押してカメラに接続。
    • しばらくすると接続確認ポップアップが表示され接続完了。
  • "Streaming" ボタン:Streamingの開始と停止を行うトグルボタン。
  • "Get" ボタン:静止画(写真)を表示するボタン。
HP of Net Camera Control (sample)

次回は

今回はネットカメラに接続しStreamingと静止画を取得する事が出来ました。次回はPTZ(Pan Tilt Zoom)機能を追加します。

SINCE 2026