OpenCVからネットワークカメラのVideoAPIを利用

ネットワークカメラ

ここでは,AXIS 211のようなHTTPアクセスのできるカメラをネットワークカメラと言う.さらに言うと,VAPIXというAPIを備えたカメラとする.
こういうカメラだと,Linuxではmplayerなどのプレイヤーを使って,こんなふうに動画をとってくることができるようになっている.

ネットワークカメラへのアクセス

以降ではAxisのカメラを対象とする.基本的には上述のAPIを備えていれば,URLを適切に変えるだけで同じように操作できる.
Axisのカメラの場合

http://user:pass@camera_address/axis-cgi/jpg/image.cgi

で画像へ,

http://user:pass@camera_address/axis-cgi/mjpg/video.cgi

で動画へアクセスすることができる.(ちなみに,user,pass,camera_addressは,そのネットワークカメラのユーザ名,パスワード,IPアドレスを入れること.)ただし,プレイヤーによっては指定したファイル名の最後(拡張子)が動画の拡張子でないと再生できない場合がある.(今の場合だと,.cgiになっている.)そこで次のようにダミーのパラメータ(type=.mjpg)をつけて指定する.

http://user:pass@camera_address/axis-cgi/mjpg/video.cgi?type=.mjpg

OpenCVからのアクセス

上述のネットワークカメラに対し,OpenCVを使ってプログラムからアクセスする.

cv::VideoCaptureを使った動画ファイルからの画像取得

普通,ローカルのPC上の動画ファイル(例えばvideo.mjpg)を開いて,そこから順に画像(cv::Mat)を取り出すコードは次のようになる

#include <cv.h>
#include <highgui.h>
int main(){
    cv::VideoCapture cam("video.mjpg"); // カメラ
    cv::Mat m; // 画像用の変数
    while((char)cv::waitKey(1)!='q'){
        cam >> m; // 画像の撮影
        /* 好きな処理 */
        cv::imshow("show",m); // 画像の表示
    }
}

結構簡単.

ネットワークカメラからの動画取得

ネットワークカメラからの場合,ファイル名の代わりに上述のURLを指定するだけでOKだった.

#include <cv.h>
#include <highgui.h>
int main(){
    cv::VideoCapture cam("http://user:pass@camera_address/axis-cgi/mjpg/video.cgi&type=.mjpg"); // カメラ
    cv::Mat m; // 画像用の変数
    while((char)cv::waitKey(1)!='q'){
        cam >> m; // 画像の撮影
        /* 好きな処理 */
        cv::imshow("show",m); // 画像の表示
    }
}

これでネットワークカメラから画像を取ってこれるはず.あとはOpenCVで好きな画像処理をすればOK.

「OpenCVからネットワークカメラのVideoAPIを利用」への7件のフィードバック

  1. はじめまして。
    AXISのネットワークカメラ&OpenCV(2.1)で映像を取り込もうと苦労していまして、ネットで調べていたらこちらの記録を拝見しました。
    ネットワークカメラはAXIS P1344で、VAPIXを使用して実現したいと思ってるのですが、まさしく私の実現したいことが出来ているのですね!
    素晴らしい!
    よしっ!っとコードをお借りして実際にTry!
    「cv::VideoCaptureを使った動画ファイルからの画像取得」はOKでした。
    しかし、「ネットワークカメラからの動画取得」の場合は”式を評価できません”の例外が発生してしまいます。
    そこで、質問です。
    1.OpenCVからネットワークカメラのVideoAPIを利用を検証された時に使用されたOpenCVのバージョンを教えていただけないでしょうか?
    2.APIであるVAPIXを使用したいのですが、PCからブラウザで初めてネットワークカメラのcamera_addressにアクセスしたときに「AXIS Media Control アドオンをインストールしますか」と聞いてきますが、この段階でVAPIXが利用できるという解釈で問題ないでしょうか?
    違う場合は、どうすればVAPIXのAPIが利用できるようになりますか?
    以上、大変ご迷惑かと思いますが、どうか宜しくお願いします。

    返信
    • 返信が遅くなり申し訳ありません.
      僕が試したときは,OpenCVは2.2だったと思います.
      たぶん2.1でも大丈夫だと思いますが….
      「AXIS Media Control アドオンをインストールしますか」というのは,単にブラウザプラグインをインストールしているだけです.今回のプログラムから画像取得とは関係ありません.
      プログラム中の,「http://user:pass@camera_address/axis-cgi/mjpg/video.cgi&type=.mjpg」
      の部分は正しく指定されていますか?
      確かvapixののバージョンによって,この部分の指定方法が若干異なっていたと思います.
      いまマニュアルを読んだところ,
      VAPIX ver.2の場合は,「http://user:pass@camera_address/mjpg/video.mjpg」
      VAPIX ver.3の場合は,
      「http://user:pass@camera_address/axis-cgi/mjpg/video.cgi」
      でアクセスできるようです.

      返信
      • 回答頂きまして有難うございました!
        vapixのバージョンによって指定方法が異なるということですね。
        参考になりました。
        ご教授いただいた内容で再度チャレンジしてみます。
        ありがとうございました!
        また、質問させて頂くかもしれませんが、その時はどうか宜しくお願いいたします。

        返信
  2. はじめまして.
    私は,現在,OpenCVを使いUSBカメラから取得した画像を物体検出等の画像処理をして,メモリ上でjpegに圧縮し,ネットワークで送信することで,ストリーミングを行っております.
    今回の記事とは,少しずれてしまうのですが,AXISのカメラの様にリアルタイムにmpegやh.264形式で画像を送信するサーバーを作るためには,どのようなことをすればよろしいのでしょうか?
    ffmpegでは,カメラから取得した画像をサーバー側で画像処理をかけることができないため,困っております.
    もし,なにか方法をご存知でしたら,教えていただけないでしょうか.
    よろしくお願いします.

    返信
    • コメントありがとうございます.
      やった事無いですが,Video4Linuxのループバックができたら,
      カメラ→ご自身の画像処理プログラム(V4L利用で出力:OSからは新しいカメラとして認識される?)→ffmpegなどのストリーミングサーバ
      でできるのではないでしょうか?
      きちんと調べていないので本当にできるかわかりませんが…

      返信

コメントする