前提・実現したいこと
openframeworksで輪郭線が壁の役割となって落ちてくるボールを弾きたい。輪郭線はポリゴン図形だと計算量が多くコマ落ちが発生してしまうらしいので、輪郭線に等間隔に円を配置してその円に当たるとボールが弾くようにしたい。画面のサイズや描画の問題かと思いまいしたが分からないのでご教授お願い致します。
visual studio 2017使用
openframeworks0.10.1使用 アドオンはofxBox2DとofxOpenCVを使用
発生している問題・エラーメッセージ
輪郭線に円を配置するが、その表示が画面の左上に表示されてしまう。
以下のように左上に輪ゴムの輪郭に円を配置したものが表示される。また、輪郭が二つ出てしまっている。実際は実際の輪ゴムの周りに等間隔に配置した円が表示されるようにしたい。
該当のソースコード
C++
1#include "ofApp.h" 2 3//-------------------------------------------------------------- 4void ofApp::setup() { 5 ofSetFrameRate(60); 6 ofBackground(0, 0, 0); 7 8 vidGrabber.listDevices();//デバイスリスト 9 vidGrabber.setDeviceID(0);//デバイスのID選択 10 11 //幅320pixel、高さ240pixelでビデオ取り込み初期化 12 vidGrabber.initGrabber(320, 240); 13 //OpenCVで解析する320pixel x 240pixelのカラー画像の領域を確保 14 colorImg.allocate(320, 240); 15 //OpenCVで解析する320pixel x 240pixelのグレースケール画像の領域を確保 16 grayImage.allocate(320, 240); 17 //背景画像として320pixel x 240pixelのグレースケール画像の領域を確保 18 grayBg.allocate(320, 240); 19 //背景との差分画像として320pixel x 240pixelのグレースケール画像の領域を確保 20 grayDiff.allocate(320, 240); 21 //閾値を100に 22 threshold = 100; 23 24 //Box2D初期設定 25 box2d.init(); //Box2Dの世界を初期化 26 box2d.setGravity(0, 5); //重力を設定、下に5の力 27 box2d.createBounds(0, 0, ofGetWidth(), ofGetHeight()); //画面を壁で囲む 28 box2d.setFPS(30); //30fpsで表示 29 box2d.checkBounds(true); 30} 31 32//-------------------------------------------------------------- 33void ofApp::update() { 34 //box2d更新 35 box2d.update(); 36 37 //新規にフレームを取り込んだかを判定する変数 38 bool bNewFrame = false; 39 //最後に取り込んだフレームから変化があったかを判定 40 vidGrabber.update(); 41 bNewFrame = vidGrabber.isFrameNew(); 42 43 //新規のフレームの場合とりこみ実行 44 if (bNewFrame) { 45 //OpenCVで解析するカラー画像領域に取得した映像を格納 46 colorImg.setFromPixels(vidGrabber.getPixels().getData(), 320, 240); 47 //取り込んだカラー映像をグレースケールに変換 48 grayImage = colorImg; 49 //背景画像と現在の画像の差分の絶対値を取得 50 grayDiff.absDiff(grayBg, grayImage); 51 //差分画像を設定した閾値を境に二値化 52 grayDiff.threshold(threshold); 53 //二値化した差分画像から、輪郭を抽出する(最小領域 20 ピクセルで最大領域は画面の 1/3 となる連続領域(blob)から最大のものを 10 個まで取り出す) 54 contourFinder.findContours(grayDiff, 20, (320 * 240) / 3, 10, false); 55 //境界線の円をクリア 56 for (int i = 0; i < contourCircles.size(); i++) { 57 contourCircles[i].get()->destroy(); 58 } 59 contourCircles.clear(); 60 //検出された物体(Blobs)の数だけ分析 61 for (int i = 0; i < contourFinder.nBlobs; i++) { 62 for (int j = 0; j < contourFinder.blobs[i].pts.size(); j += 4) { 63 //輪郭線にそって等間隔に座標を抽出 64 ofPoint pos = contourFinder.blobs[i].pts[j]; 65 //輪郭線に並べるofxBox2dCircleを追加 66 ofPtr<ofxBox2dCircle> ContourCircles = ofPtr<ofxBox2dCircle>(new ofxBox2dCircle); 67 ContourCircles.get()->setup(box2d.getWorld(), pos.x, pos.y, 4); 68 //Vector配列contourCirclesに追加 69 contourCircles.push_back(ContourCircles); 70 } 71 } 72 } 73} 74 75//-------------------------------------------------------------- 76void ofApp::draw() { 77 //画面に対する映像の比率を計算 78 float ratioX = ofGetWidth() / 320; 79 float ratioY = ofGetHeight() / 240; 80 81 82 //検出した解析結果を表示 83 ofPushMatrix(); 84 //画面サイズいっぱいに表示されるようリスケール 85 ofScale((float)ofGetWidth() / (float)grayDiff.width, (float)ofGetHeight() / (float)grayDiff.height); 86 //ソースの映像を描画 87 ofSetColor(255, 255, 255); 88 colorImg.draw(0, 0); 89 //解析結果を描画 90 contourFinder.draw(); 91 //境界線の円を描画 92 ofNoFill(); 93 ofSetColor(255, 0, 0); 94 for (int i = 0; i < contourCircles.size(); i++) { 95 contourCircles[i]->draw(); 96 for (int i = 0; i < contourFinder.nBlobs; i++) { 97 contourFinder.blobs[i].draw(360, 540); 98 }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/10/30 12:08