学生の時にもっと画像処理系の研究しておくべきだった。
openFrameworksにはopenFrameworks用のopenCVライブラリofxopenCVが用意されているのだけど、openCVよりもできることが限られてる気がしました。
例えば、watershedアルゴリズムを使って領域分割しようとしてもofxopenCV用にはその関数が用意されていなかったり。直接openCVも使えるので多分そっち使ってってことだとは思うけど。
以下、openFrameworks内でwatershedアルゴリズムを実装した方法です。
1、ofxCvClolorImageのインスタンスに画像を読み込む
ofImage buf; ofxCvColorImage ofxSrc; buf.loadImage("munk.jpeg"); ofxSrc.setFromPixels(buf.getPixels(), buf.width, buf.height);
2、openCVの画像データ構造体IplImageの入力画像、マーカー画像、出力画像用インスタンスを生成する。
この時、marker用画像のdepthは IPL_DEPTH_32S、nchannelは1にしなければエラーになる。(ここに詰まった。)
IplImage *srcImg, *markers, *dstImg; srcImg = ofxSrc.getCvImage(); markers = cvCreateImage(cvGetSize(srcImg), IPL_DEPTH_32S, 1); //depth, nchannelに注意 cvZero(markers); dstImg = cvCloneImage(srcImg);
3、watershedアルゴリズム用のマーカーをランダムに分割数(この例では200個にした)作成する
int seed_rad = 20; static int seed_num = 0; for(int i=0;iwidth), ofRandom(srcImg->height)); cvCircle (markers, pt, seed_rad, cvScalarAll (seed_num), CV_FILLED, 8, 0); }
4、watershedアルゴリズムを実行し、出力画像に結果を代入する。
cvWatershed(srcImg, markers); // 実行結果の画像中のwatershed境界(ピクセル値=-1)を結果表示用画像上に表示する int *idx; for (int i = 0; i < markers->height; i++) { for (int j = 0; j < markers->width; j++) { idx = (int *) cvPtr2D (markers, i, j, NULL); if (*idx == -1) cvSet2D (dstImg, i, j, cvScalarAll (255)); } }
5、最後に画面描画ができるように用にofxCvClolorImageに結果画像を代入する。
ofxCvColorImage ofxSrc,ofxDst; ofxDst.allocate(dstImg->width, dstImg->height); ofxDst = dstImg;
ムンクの画像を分割した結果がこれ。
0 件のコメント:
コメントを投稿