NtKinect: Kinect V2 C++ Programming with OpenCV on Windows10

Kinect V2 で Video 録画する


2016.07.20: created by
Japanese English
目次へ

前提として理解しておくべき知識


OpenCV の動画作成用クラス cv::VideoWriter

cv::VideoWriterクラスのコンストラクタとメソッド

OpenCV cv::VideoWriter Class Reference
返り値の型 メソッド名 説明
コンストラクタ cv::VideoWriter(const String& filename ,
    int fourcc ,
    double fps ,
    cv::Size frameSize ,
    bool isColor = true )
コンストラクタ。
引数
filename
出力ビデオファイルの名前
fourcc
codecを表す4文字コード。 Video Codecs by FOURCC
fps
フレームレート。Frame Per Second
frameSize
ビデオフレームのサイズ
isColor
カラー画像かどうか。
  • ".avi" --- XVID
  • ".mp4" --- FMP4, MP4V
bool isOpened() VideoWriterが正しく初期化されているか。
void write(const cv::Mat& image ) image をビデオフレームとしてストリームに書き込む。
VideoWriter& operator<<(const cv::Mat& image ) image をビデオフレームとしてストリームに書き込む。
void release() VideoWriter をcloseする。

OpenCVには複数のcv::Matから動画を作成する cv::VideoWriter が存在します。 cv::VideoWriter が対応している動画形式のうち、 いろいろなプラットホームで再生可能なのは ".avi" ファイルです。 ただし、書き込む画像 cv::Mat の形式は BGRA では駄目で、BGR に変換する必要があります。 また、解像度も変換して小さくする必要があります。

    NtKinect kinect;
    cv::Size sz(640,480);
    cv::VideoWriter vw("videofile.avi", CV_FOURCC_MACRO('X','V','I','D'), 20.0, sz, true);
    if (! vw.isOpened()) throw runtime_error("cannot create videowriter");
    cv:Mat img ;  // 新しい cv::Mat を用意して
    while (1) {
        kinect.setRGB();
        cv::resize(kinect.rgbImage, img, sz, 0, 0); // 解像度を 640x480 に変換する
        cv::cvtColor(kinect.rgbImage, img , CV_BGRA2BGR); // BGRAからBGRへ変換する
        vw << img;     // vw.write(img) と同じ
        ...
    }
    vw.release();

プログラム作成の手順

  1. NtKinect: Kinect V2 でRGBカメラ画像を取得する(基本設定)」 の Visual Studio 2015 のプロジェクト KinectV2.zipを用いて作成します。
  2. main.cppの内容を以下のように変更します。
  3. cv::VideoWriter を用意します。

    kinect.setRGB()メソッドを呼び出して kinect.rgbImage にRGB画像を設定します。 kinect.rgbImage の各画素は BGRA フォマットであるので、これを BGR フォーマットに変換してから cv::VideoWriter に write します。

    日付と時刻をファイル名とする avi ファイルを生成します。

    コメントアウトしてある部分を使うと mp4 ファイルを生成します。 が、私の手元ではここで生成した mp4 ファイルは、再生できるシステム Windows10 とできないシステム Windows8 がありました。aviファイルの方がサイズは大きくなりますが、問題は起こりにくいようです。

    main.cpp
    #include <iostream>
    #include <sstream>
    
    #include "NtKinect.h"
    
    using namespace std;
    
    #include <time.h>
    string now() {
      char s[1024];
      time_t t = time(NULL);
      struct tm lnow;
      localtime_s(&lnow, &t);
      sprintf_s(s, "%04d-%02d-%02d_%02d-%02d-%02d", lnow.tm_year + 1900, lnow.tm_mon + 1, lnow.tm_mday, lnow.tm_hour, lnow.tm_min, lnow.tm_sec);
      return string(s);
    }
    
    void doJob() {
      NtKinect kinect;
      cv::VideoWriter vw;
      int scale = 1;
      cv::Size sz(1920/scale,1080/scale);
      bool onSave = false;
      cv::Mat img;
      while (1) {
        kinect.setRGB();
        if (onSave) {
          cv::resize(kinect.rgbImage, img, sz, 0, 0);
          cv::cvtColor(img, img, CV_BGRA2BGR);
          vw << img;
        }
        cv::imshow("rgb", kinect.rgbImage);
        auto key = cv::waitKey(33);
        if (key == 'q') break;
        else if (key == 'r' && !onSave) {
          vw = cv::VideoWriter(now()+".avi",CV_FOURCC_MACRO('X','V','I','D'), 30.0, sz);
          //vw = cv::VideoWriter(now()+".mp4",CV_FOURCC_MACRO('F','M','P','4'), 30.0, sz);
          //vw = cv::VideoWriter(now()+".mp4",CV_FOURCC_MACRO('M','P','4','V'), 30.0, sz);
          if (!vw.isOpened()) throw runtime_error("cannot create video file");
          onSave = true;
        } else if (key == 's' && onSave) {
          vw.release();
          onSave = false;
        }
      }
      cv::destroyAllWindows();
    }
    
    int main(int argc, char** argv) {
      try {
        doJob();
      } catch (exception &ex) {
        cout << ex.what() << endl;
        string s;
        cin >> s;
      }
      return 0;
    }
    
    
  4. プログラムを実行するとRGB画像が表示されます。 'r' キーでビデオ録画開始で、's'キーで録画停止です。 'q' キーで終了します。
  5. "日付時刻.avi" が KinectV2_video/KinectV2/ の下にできています。

  6. サンプルのプロジェクトはこちら KinectV2_vide.zip
  7. 上記のzipファイルには必ずしも最新の NtKinect.h が含まれていない場合があるので、 こちらから最新版をダウンロードして 差し替えてお使い下さい。



http://nw.tsuda.ac.jp/