サクッと導入したOpenCVですが、openFrameworksと連携できなければ意味がありません。OpenCVでは、cv::Matクラスを使うのでopenFrameworksのデータと、このcv::Matの変換は必須です。
と言っても、非常に簡単で、openFrameworksのofVideoGrabberで取得したカメラ入力をcv::Matにコンバート、cv::Matで色変換、結果をopenFrameworksで描画するコードは、こんな感じです。
ofApp.h
class ofApp : public ofxiOSApp {
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);
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 cvColor = cv::Mat(grabber.getWidth(), grabber.getHeight(), CV_8UC3, grabber.getPixels());
cv::Mat grayColor;
cv::cvtColor(cvColor, grayColor, CV_BGR2GRAY);
cv::Mat binColor;
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);
}
実行結果
ofVideoGrabberのピクセルデータをフォーマットで渡すだけです。
cv::MatからofTextureへの変換もフォーマット指定で渡すだけ。なんですが、グレースケールにした後、ofTextureへうまく戻せなかったので、一旦RGBでバッファに変換してからGL_RGBで渡しています。
たしかグレースケールならGL_LUMINANCEで変換できると思ったんですけどうまくいかなかった。
ちなみに、前回のOpenCV導入記事はこちら。hellkite.hatenablog.com