5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OpenCVとSDLを連携させてみた

Last updated at Posted at 2017-03-21

OpenCVhighguiには簡易的な機能しかないので、SDLと連携させてみました。
OpenCVのcv::VideoCaptureでWebカメラの映像を取得して、SDLでレンダリングしました。

環境

  • OS: ArchLinux 64bit
  • 言語: C++
  • コンパイラ: clang++
  • ライブラリ: OpenCV3.2, SDL2.0.5

どうやって連携させるか

OpenCVのcv::Matクラスはピクセルデータに直接アクセスする方法を提供しています。また、SDLのSDL_Texture構造体はピクセルデータを書き込む方法を提供しています。
今回はcv::VideoCaptureでカメラの映像をcv::Matクラスに格納し、そのピクセルデータをSDL_Texture構造体に書き込んでそれをレンダリングしました。

cv::Matクラスのピクセルデータへのアクセス

cv::Matクラスのピクセルデータへのアクセス方法は、主に以下の5通りとされています。

  • cv::Mat::at
  • cv::Mat::data
  • cv::Mat::ptr
  • cv::MatIterator_
  • cv::Point

今回は一番高速とされるcv::Mat::ptrを利用しました。
以下はカラー画像の全てのピクセルの値を青・緑・赤の順に標準出力するコードです。

for (auto row { 0 }; row < mat.rows; ++row)
{
    auto const data { mat.ptr<Vec3b>(row) };

    for (auto col { 0 }; col < mat.cols; ++col)
    {
        std::cout << data[col][0] << "," << data[col][1] << "," << data[col][2] << std::endl;
    }
}

SDL_Texture構造体のピクセルデータへの書き込み

SDL_Texture構造体のピクセルデータへの書き込みは、SDL_UpdateTextureを用いる方法とSDL_LockTextureを用いる方法の2つがありますが、今回は速いとされるSDL_LockTextureを利用しました。
書き込みは以下の手順で行います。

書き込み可能なSDL_Texture構造体を作成する

SDL_CreateTextureの第3引数ではテクスチャのアクセスパターンを指定できるのですが、SDL_TEXTUREACCESS_STREAMINGを指定することで書き込み可能なSDL_Texture構造体を作成できます。

auto texture {
    SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 640, 480)
};

SDL_Texture構造体を書き込み専用にするためにロックする

SDL_LockTextureを用いることで、テクスチャをロックしてピクセルデータへのポインタと水平方向のバイト数を取得することができます。ピクセルデータの書き込み操作はこのポインタに対して行います。

void *pixels;

int32_t pitch;

SDL_LockTexture(texture, nullptr, &pixels, &pitch);

ポインタを介してピクセルデータを書き込む

先ほど取得したポインタを介してピクセルデータを書き込みます。ピクセルデータは1次元の配列状に並んでいるので、任意の座標のピクセルに書き込む際は水平方向のバイト数を考慮して、書き込むピクセルの位置を計算しなければなりません。
以下は1024番目のピクセルを白くするコードです。

auto const format { SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888) };

reinterpret_cast<uint32_t *>(pixels)[1024] = SDL_MapRGB(format, 255, 255, 255);

書き込み終わったSDL_Texture構造体をアンロックする

SDL_UnlockTextureでテクスチャをアンロックしてピクセルデータの変更を反映します。

SDL_UnlockTexture(texture);

参考文献

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?