質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
openFrameworks

openFrameworksは、C++で記述されたライブラリ群です。既存のライブラリの設定なしで使用できるため「糊」のようなツールキットと呼ばれています。簡単なコードだけで様々なグラフィックスやインタラクションをデザインすることが可能です。

Box2D

Box2Dは、C++で記述された2D物理演算エンジン。C++以外にも多くの言語に移植されています。円形・多角形の物体の運動をシミュレーションすることが可能で、GUIで動作を確認できるテストベッドが付属されています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

953閲覧

openframeworksでの輪郭線の表示のされ方に困っています

nggn64

総合スコア9

openFrameworks

openFrameworksは、C++で記述されたライブラリ群です。既存のライブラリの設定なしで使用できるため「糊」のようなツールキットと呼ばれています。簡単なコードだけで様々なグラフィックスやインタラクションをデザインすることが可能です。

Box2D

Box2Dは、C++で記述された2D物理演算エンジン。C++以外にも多くの言語に移植されています。円形・多角形の物体の運動をシミュレーションすることが可能で、GUIで動作を確認できるテストベッドが付属されています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/10/29 05:32

編集2019/10/30 05:43

前提・実現したいこと

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 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

位置がずれているのは描画する画像と解析結果の描画のスケールが合っていないことが原因の一つかと思われます。
一度 ofScale((float)ofGetWidth() / (float)grayDiff.width, (float)ofGetHeight() / (float)grayDiff.height)をコメントアウトして実行してみてください。

ソース全文がないので推測ですが、輪郭が二つ描画されているのはおそらく描画する関数を別の場所で2回呼び出している可能性が高いです。
ソースコードは書いた通りに動きますので、前回と同様一つ一つの関数の役割を理解していくと解決が早くなります。

投稿2019/10/30 10:48

Kapustin

総合スコア1186

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nggn64

2019/10/30 12:08

返信ありがとうございます。 ofScale((float)ofGetWidth() / (float)grayDiff.width, (float)ofGetHeight() / (float)grayDiff.height)のコメントアウトとモニタ画面表示を調節したところ上手く表示されるようになりました。 また、境界線の円を描画の for (int i = 0; i < contourFinder.nBlobs; i++) { contourFinder.blobs[i].draw(360, 540); } のところをコメントアウトにして実行したところ輪郭を1つだけ出すことができました。 毎回的確に問題の原因を指摘してくださり、本当に勉強になります。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問