hellkite 日記と雑記とメモ。

Shiki Kazamaの駄文と音楽と、時々技術な感じ

openFrameworks for iOSでOpenCVのcv::Matを使う


スポンサーリンク


サクッと導入したOpenCVですが、openFrameworksと連携できなければ意味がありません。OpenCVでは、cv::Matクラスを使うのでopenFrameworksのデータと、このcv::Matの変換は必須です。

と言っても、非常に簡単で、openFrameworksのofVideoGrabberで取得したカメラ入力をcv::Matにコンバート、cv::Matで色変換、結果をopenFrameworksで描画するコードは、こんな感じです。

ofApp.h

class ofApp : public ofxiOSApp {
  // (中略)

  // Grabber
  ofVideoGrabber grabber;
  ofTexture tex;
  unsigned char * pix;
};

ofApp.mm

#include "ofApp.h"

#ifdef __cplusplus
#include <opencv2/opencv.hpp>
#endif

//--------------------------------------------------------------
void ofApp::setup(){

  ofSetOrientation(OF_ORIENTATION_90_RIGHT);
  ofSetFrameRate(30);

  // ofVideoGrabberを初期化する
  grabber.initGrabber(320, 568, OF_PIXELS_BGRA);

  // テクスチャを確保
  tex.allocate(grabber.getWidth(), grabber.getHeight(), GL_RGB);

  // バッファを確保
  pix = new unsigned char [ (int)(grabber.getWidth() * grabber.getHeight() * 3.0)];
}

//--------------------------------------------------------------
void ofApp::update(){
  // カメラからの入力の取得と検出処理

  // カメラ入力を取得
  grabber.update();

  // cv::Mat形式に変換(OpenCVはBGR配列が標準)
  cv::Mat cvColor = cv::Mat(grabber.getWidth(), grabber.getHeight(), CV_8UC3, grabber.getPixels());
  // 色変換
  cv::Mat grayColor;
  cv::cvtColor(cvColor, grayColor, CV_BGR2GRAY);
  cv::Mat binColor; // 2値化
  cv::threshold(grayColor, binColor, 128, 255, cv::THRESH_BINARY);

  int totalPixel = grabber.getWidth() * grabber.getHeight();
  for (int i = 0; i < totalPixel; i++) {
    pix[3*i+0] = binColor.data[i];
    pix[3*i+1] = binColor.data[i];
    pix[3*i+2] = binColor.data[i];
  }

  // 結果を表示
  tex.loadData(pix, grabber.getWidth(), grabber.getHeight(), GL_RGB);
}

//--------------------------------------------------------------
void ofApp::draw(){
  // カメラからの入力を描画
  grabber.draw(0, 0);

  // 結果のテクスチャを描画
  tex.draw(0, 0, tex.getWidth() / 2, tex.getHeight() / 2);
}

実行結果
f:id:deis:20150623005243p:plain

ofVideoGrabberのピクセルデータをフォーマットで渡すだけです。
cv::MatからofTextureへの変換もフォーマット指定で渡すだけ。なんですが、グレースケールにした後、ofTextureへうまく戻せなかったので、一旦RGBでバッファに変換してからGL_RGBで渡しています。
たしかグレースケールならGL_LUMINANCEで変換できると思ったんですけどうまくいかなかった。

ちなみに、前回のOpenCV導入記事はこちら。hellkite.hatenablog.com