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.