aa develop

開発と成長

openFrameworksで3Dデータを読み込む

openFrameworksで,3Dデータを読み込んでみた.使ったのはつぼみの3Dデータ.以下からダウンロードできる. つぼみを3Dプリントできまっす! | つぼみオフィシャルサイトへようこそ! ダウンロードしたobjデータをprojectのbin/dataに置く.

プログラムを実行すると以下のようになる. f:id:aa_debdeb:20160714110739p:plain

ただ,上手くライトを当てられず顔がはっきりと見えない.ライトの使い方がまだまだ難しい.

ofApp.h

#pragma once

#include "ofMain.h"
#include "ofxAssimpModelLoader.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();
    
    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);
    
    ofxAssimpModelLoader model;
    ofEasyCam cam;
    ofLight light;
};
ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(50, 50, 50, 0);
    ofEnableDepthTest();
    ofEnableSmoothing();
    model.loadModel("tsubomi.obj");
}

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

}

//--------------------------------------------------------------
void ofApp::draw(){
    
    light.enable();
    ofEnableSeparateSpecularLight();
    ofEnableLighting();
    
    cam.begin();
    ofSetColor(255, 255, 255, 255);
    
    model.setScale(0.75, 0.75, 0.75);
    model.setPosition(0, 0, 0);
    model.drawFaces();
    cam.end();
    
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

openFrameworks/load3d at master · aa-debdeb/openFrameworks

参考

openFrameworksのofLight, ofMaterialの機能を調べる

openFrameworksのofLightとofMaterialの機能について調べるために,guiでofLight, ofMaterialのパラメータを操作できるプログラムを書いた.

f:id:aa_debdeb:20160714110639p:plain

ambient colorは全体,diffuse colorは反射しているところ,specular colorは強く反射しているところの色を決定する. ofLightとofMaterialのどちらにも,ambient color,diffuse color,specular colorを設定することができる.違いはofLightはライトが直接当たっているところだけに影響,ofMaterialはライトが当たっていないところにも影響するということ. ofMaterialのemissive colorは物体自体の色(発光色?)を決定しており,shinessはdiffuse colorにする部分とspecular colorにする部分の割合を決定している.

以下,コード.

なぜかofLightとofxGuiを組み合わせるときは,draw関数内でofxPanelインスタンスのdrawメソッドを呼び出す前に以下を入れないとguiが上手く表示されないので注意.


glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);

ofMain.h

#pragma once

#include "ofMain.h"
#include "ofxGui.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();
    
    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);
    
    ofxPanel gui;
    ofParameter specular_light, diffuse_light, ambient_light,
                specular_material, diffuse_material, ambient_material, emmisive_material;
    ofParameter is_box;
    ofParameter shiness_material;
    
    ofLight light;
    ofMaterial material;
    ofEasyCam cam;
};
ofMain.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0);
    ofEnableDepthTest();
    ofEnableSmoothing();
    gui.setup();
    gui.add(is_box.set("box", false));
    gui.add(specular_light.set("specular", ofFloatColor(0.5, 0.5, 0.5), ofFloatColor(0, 0, 0), ofFloatColor(1, 1, 1)));
    gui.add(diffuse_light.set("diffuse", ofFloatColor(0.5, 0.5, 0.5), ofFloatColor(0, 0, 0), ofFloatColor(1, 1, 1)));
    gui.add(ambient_light.set("ambient", ofFloatColor(0.5, 0.5, 0.5), ofFloatColor(0, 0, 0), ofFloatColor(1, 1, 1)));
    gui.add(specular_material.set("specular", ofFloatColor(0.5, 0.5, 0.5), ofFloatColor(0, 0, 0), ofFloatColor(1, 1, 1)));
    gui.add(diffuse_material.set("diffuse", ofFloatColor(0.5, 0.5, 0.5), ofFloatColor(0, 0, 0), ofFloatColor(1, 1, 1)));
    gui.add(ambient_material.set("ambient", ofFloatColor(0.5, 0.5, 0.5), ofFloatColor(0, 0, 0), ofFloatColor(1, 1, 1)));
    gui.add(emmisive_material.set("emmisive", ofFloatColor(0.5, 0.5, 0.5), ofFloatColor(0, 0, 0), ofFloatColor(1, 1, 1)));
    gui.add(shiness_material.set("shiness", 0, -128, 128));
}

//--------------------------------------------------------------
void ofApp::update(){
    
}

//--------------------------------------------------------------
void ofApp::draw(){
    
    material.setShininess(shiness_material);
    material.setEmissiveColor(emmisive_material);
    material.setAmbientColor(ambient_material);
    material.setDiffuseColor(diffuse_material);
    material.setSpecularColor(specular_material);

    cam.begin();
    
    light.enable();
    light.setSpotlight();
    light.setPosition(-100, 100, 100);
    light.setAmbientColor(ambient_light);
    light.setDiffuseColor(diffuse_light);
    light.setSpecularColor(specular_light);
    
    if(is_box){
        ofBoxPrimitive box;
        box.set(150);
        box.setPosition(0, 0, 0);
        material.begin();
        box.draw();
        material.end();
    } else {
        ofSpherePrimitive sphere;
        sphere.set(100, 90);
        sphere.setPosition(0, 0, 0);
        material.begin();
        sphere.draw();
        material.end();
    }
    light.disable();
    
    cam.end();
 
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);
    gui.draw();
}


//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

openFrameworks/lightCheck at master · aa-debdeb/openFrameworks

参考

openFrameworksでカメラの映像を3Dにする

OpenFrameworksでカメラ画像を3D空間上に表示するプログラムを書いた.各点の輝度をz値にしている似非立体画像.本当はlightオブジェクトを置いて陰影をつけたかったが,まだofLightについて理解してないため断念. f:id:aa_debdeb:20160714110355p:plain

下の画像は,ワイヤフレームだけを表示したもの.こっちのほうが3Dっぽい. f:id:aa_debdeb:20160714110453p:plain

コードは以下.

ofApp.h

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();
    
    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);
        
    
    ofVideoGrabber videoGrabber;
    ofMesh mesh;
    float xInterval, yInterval;
};
ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0);
    
    videoGrabber.setup(80, 60);
    xInterval = float(ofGetWidth()) / videoGrabber.getWidth();
    yInterval = float(ofGetHeight()) / videoGrabber.getHeight();
    
    ofEnableDepthTest();
    ofEnableSmoothing();
    mesh.setMode(OF_PRIMITIVE_TRIANGLES);
    mesh.enableColors();
    mesh.enableIndices();
    
}

//--------------------------------------------------------------
void ofApp::update(){
    videoGrabber.update();
    
    if(videoGrabber.isFrameNew()){
        unsigned char * pixels = videoGrabber.getPixels();
        
        mesh.clearVertices();
        mesh.clearColors();
        mesh.clearIndices();
        for(int h = 0; h < videoGrabber.getHeight(); h++){
            for(int w = 0; w < videoGrabber.getWidth(); w++){
                float r = (float)pixels[int(h * videoGrabber.getWidth() + w) * 3] / 256.0;
                float g = (float)pixels[int(h * videoGrabber.getWidth() + w) * 3 + 1] / 256.0;
                float b = (float)pixels[int(h * videoGrabber.getWidth() + w) * 3 + 2] / 256.0;
                ofFloatColor color = ofFloatColor(r, g, b);
                float z = ofMap(color.getBrightness(), 0, 1, 300, -300);
                mesh.addColor(color);
                mesh.addVertex(ofVec3f(w * xInterval, h * yInterval, z));
            }
        }
        for(int h = 0; h < videoGrabber.getHeight() - 1; h++){
            for(int w = 0; w < videoGrabber.getWidth() - 1; w++){
                mesh.addIndex(h * videoGrabber.getWidth() + w);
                mesh.addIndex(h * videoGrabber.getWidth() + w + 1);
                mesh.addIndex((h + 1) * videoGrabber.getWidth() + w + 1);
                mesh.addIndex(h * videoGrabber.getWidth() + w);
                mesh.addIndex((h + 1) * videoGrabber.getWidth() + w);
                mesh.addIndex((h + 1) * videoGrabber.getWidth() + w + 1);
            }
        }
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    mesh.draw();
//    mesh.drawWireframe();
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

openFrameworks/camera3d at master · aa-debdeb/openFrameworks

参考

openFrameworksで背景をグラデーションにする

openFrameworksの背景を簡単にグラデーションにするofBackgroundGradientという関数があるので試してみた.

OF_GRADIENT_CIRCULAR

f:id:aa_debdeb:20160714110143p:plain

OF_GRADIENT_LINEAR

f:id:aa_debdeb:20160714110219p:plain

OF_GRADIENT_BAR

f:id:aa_debdeb:20160714110241p:plain

本当は,modeの設定をラジオボタンにしたかったが,ofxGuiでのやり方がわからず断念.そもそもofxGuiにラジオボタンがあるのかな?

ofMain.h

#pragma once

#include "ofMain.h"
#include "ofxGui.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();
    
    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);
    
    ofxPanel gui;
    ofParameter startColor, endColor;
    ofParameter mode_id;
};
ofMain.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    gui.setup();
    gui.add(mode_id.set("mode", 0, 0, 2));
    gui.add(startColor.set("start color", ofColor(54, 230, 140), ofColor(0, 0), ofColor(255, 255)));
    gui.add(endColor.set("end color", ofColor(255, 140, 0), ofColor(0, 0), ofColor(255, 255)));
}

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

}

//--------------------------------------------------------------
void ofApp::draw(){
    ofGradientMode mode;
    switch(mode_id){
        case 0:
            mode = OF_GRADIENT_CIRCULAR;
            break;
        case 1:
            mode = OF_GRADIENT_LINEAR;
            break;
        case 2:
            mode = OF_GRADIENT_BAR;
            break;
    }
    ofBackgroundGradient(startColor, endColor, mode);
    gui.draw();
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

openFrameworks/backgroundGradient at master · aa-debdeb/openFrameworks

参考

OpenCVでカメラ画像をアニメ風にする(K-meansによる減色)

この前に,OpenCVでカメラ画像をアニメ風にするプログラムを書いた.そのときは減色に量子化を用いた.

今回は,減色にK-meansを用いて,同じことをやってみた.結果は以下のようになる. f:id:aa_debdeb:20160714110019p:plain

K-meansを使った方が色の数が少なくても,それなりに元の画像の雰囲気が残るのがいいところ.ただ処理が重たいため,カメラ画像をリアルタイムに処理して滑らかに再生することは難しい.

以下,コード.

main.cpp

//
//  main.cpp
//  videoAbstraction_Kmeans
//
//  Created by 朝倉aa_debdeb on 2015/11/17.
//  Copyright (c) 2015年 aa_debdeb. All rights reserved.
//

#include 
#include 
#include "opencv2/opencv.hpp"

cv::Mat getAnimeMat(cv::Mat img){
    cv::Mat canny_img;
    cv::Canny(img, canny_img, 50, 200);
    
    const int cluster_count = 16;
    cv::Mat points;
    img.convertTo(points, CV_32FC3);
    points = points.reshape(3, img.rows * img.cols);
    cv::Mat_ clusters(points.size(), CV_32SC1);
    cv::Mat centers;
    cv::kmeans(points, cluster_count, clusters,
               cvTermCriteria(CV_TERMCRIT_EPS|CV_TERMCRIT_ITER, 10, 1.0), 1, cv::KMEANS_PP_CENTERS, centers);
    cv::Mat anime_img(img.size(), img.type());
    cv::MatIterator_ itd = anime_img.begin(),
        itd_end = anime_img.end();
    cv::MatIterator_ canny_itd = canny_img.begin();
    for(int i = 0; itd != itd_end; ++itd, ++canny_itd, ++i){
        if(*canny_itd == 255){
            (*itd)[0] = 0;
            (*itd)[1] = 0;
            (*itd)[2] = 0;
        } else {
            cv::Vec3f &color = centers.at(clusters(i), 0);
            (*itd)[0] = cv::saturate_cast(color[0]);
            (*itd)[1] = cv::saturate_cast(color[1]);
            (*itd)[2] = cv::saturate_cast(color[2]);
        }
    }

    return anime_img;
}


int main(int argc, const char * argv[]) {
//        cv::Mat img = cv::imread("lenna.jpg", 1);
//        if(img.empty()) return -1;
//    
//        cv::Mat anime_img = getAnimeMat(img);
//        cv::imshow("anime image", anime_img);
//        cv::waitKey(0);
    
    cv::VideoCapture cap(0);
    cv::Mat img;
    while(cv::waitKey(1) != 'q'){
        cap >> img;
        cv::Mat anime_img = getAnimeMat(img);
        cv::imshow("anime image", anime_img);
    }
    
}

OpenCV/videoAbstraction_Kmeans at master · aa-debdeb/OpenCV

参考

OpenCVでカメラ画像をアニメ風にする

OPenCVでカメラから取得した映像をアニメ風にして表示するプログラムを書いた.具体的には,取得した画像の各ピクセルのRGB値を適当な段階に量子化する.その上にCanny法で検出したエッジを黒で重ねている.結果として,カメラで取得した画像が以下のようになる.

f:id:aa_debdeb:20160714105819p:plain

こういう画像処理はVideo Absractionというらしい.

本当は,ofxCvアドオンを使って,openFrameworksで作りたかったが,上手く動かすことができず.OpenCV自体をもっと勉強してからもう一回チャレンジする.

以下がコード.

main.cpp

//
//  main.cpp
//  videoAbstraction
//
//  Created by aa_debdeb on 2015/11/16.
//
//

#include 
#include 
#include "opencv2/opencv.hpp"

cv::Mat getAnimeMat(cv::Mat img){
    cv::Mat canny_img, anime_img;
    cv::Canny(img, canny_img, 50, 200);
    anime_img = cv::Mat(cv::Size(img.cols, img.rows), CV_8UC3);
    int color_step_num = 8;
    float color_step_size = float(255) / color_step_num;
    for(int y = 0; y < img.rows; y++){
        for(int x = 0; x < img.cols; x++){
            if(canny_img.at(y, x) == 255){
                anime_img.at(y, x) = cv::Vec3b(0, 0, 0);
            } else {
                cv::Vec3b img_color = img.at(y, x);
                cv::Vec3b anime_color = cv::Vec3b(255, 255, 255);
                for(int ci = 0; ci < 3; ci++){
                    for(float level = color_step_size / 2; level < 255; level += color_step_size){
                        if(fabs(img_color[ci] - level) <= color_step_size / 2){
                            anime_color[ci] = level;
                            break;
                        }
                    }
                }
                anime_img.at(y, x) = cv::Vec3b(anime_color[0], anime_color[1], anime_color[2]);
            }
        }
    }
    return anime_img;
}


int main(int argc, const char * argv[]) {
//    cv::Mat img = cv::imread("lenna.jpg", 1);
//    if(img.empty()) return -1;
//
//    cv::Mat anime_img = getAnimeMat(img);
//    cv::imshow("anime image", anime_img);
//    cv::waitKey(0);

    cv::VideoCapture cap(0);
    cv::Mat img;
    while(cv::waitKey(1) != 'q'){
        cap >> img;
        cv::Mat anime_img = getAnimeMat(img);
        cv::imshow("anime image", anime_img);
    }
    
}

OpenCV/videoAbstraction at master · aa-debdeb/OpenCV

参考

オプティカルフローでパーティクルを操作する

openFrameworksのofxCvアドオンを使って,オプティカルフローを計算する.オプティカルフローのベクトル値に基づき,パーティクルを動かす.

f:id:aa_debdeb:20160714105631p:plain

オプティカルフローを使うとインタラクティブな何か面白いものを作れそうな気がするが,アイデアが浮かばない.もう少し画像処理について勉強したら何か思いつくかも.

ofApp.h

#pragma once

#include "ofMain.h"
#include "ofxCv.h"
#include "ofxGui.h"
#include "particle.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();

    void keyPressed(int key);
    void keyReleased(int key);
    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void mouseEntered(int x, int y);
    void mouseExited(int x, int y);
    void windowResized(int w, int h);
    void dragEvent(ofDragInfo dragInfo);
    void gotMessage(ofMessage msg);
    

    ofVideoGrabber camera;
    ofxCv::FlowFarneback fbFlow;
    
    ofxPanel gui;
    ofParameter fbPyrScale, fbPolySigma;
    ofParameter fbLevels, fbIterations, fbPolyN, fbWinSize;
    ofParameter fbUseGaussian;
    
    vector particles;
    
    void drawFlow1();
    void drawFlow2();
    
};
ofApp.cpp

#include "ofApp.h"

using namespace ofxCv;
using namespace cv;

//--------------------------------------------------------------
void ofApp::setup(){
    ofSetFrameRate(60);
    
    camera.setup(320, 240);
    
    gui.setup();
    gui.add(fbPyrScale.set("fbPyrScale", .5, 0, .99));
    gui.add(fbLevels.set("fbLevels", 4, 1, 8));
    gui.add(fbIterations.set("fbIterations", 2, 1, 8));
    gui.add(fbPolyN.set("fbPolyN", 7, 5, 10));
    gui.add(fbPolySigma.set("fbPolySigma", 1.5, 1.1, 2));
    gui.add(fbUseGaussian.set("fbUseGaussian", false));
    gui.add(fbWinSize.set("winSize", 32, 4, 64));
    
    particles = vector();
    for(int i = 0; i < 1000; i++){
        particles.push_back(Particle());
    }
}

//--------------------------------------------------------------
void ofApp::update(){
    camera.update();
    fbFlow.setPyramidScale(fbPyrScale);
    fbFlow.setNumLevels(fbLevels);
    fbFlow.setWindowSize(fbWinSize);
    fbFlow.setNumIterations(fbIterations);
    fbFlow.setPolyN(fbPolyN);
    fbFlow.setPolySigma(fbPolySigma);
    fbFlow.setUseGaussian(fbUseGaussian);
    fbFlow.calcOpticalFlow(camera);
    
    for(int i = 0; i < particles.size(); i++){
        float adjustedX = particles[i].position.x * float(camera.getWidth()) / ofGetWidth();
        float adjustedY = particles[i].position.y * float(camera.getHeight()) / ofGetHeight();
        ofVec2f force = fbFlow.getFlowOffset(adjustedX, adjustedY) * 3;
        particles[i].serForce(force);
        particles[i].update();
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofSetColor(255);
    camera.draw(0, 0, ofGetWidth(), ofGetHeight());
    fbFlow.draw(0, 0, ofGetWidth(), ofGetHeight());
    
    for(int i = 0; i < particles.size(); i++){
        particles[i].draw();
    }
    
    gui.draw();
}


//--------------------------------------------------------------
void ofApp::keyPressed(int key){

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}
particle.h

//
//  particle.h
//  opticalFlowApp1
//
//  Created by aa_debdeb on 2015/11/15.
//
//

#ifndef __opticalFlowApp1__particle__
#define __opticalFlowApp1__particle__

#include 
#include "ofMain.h"

class Particle {

public:
    
    Particle();
    void update();
    void draw();
    void borders();
    void serForce(ofVec2f _force);
    ofVec2f position;
    ofVec2f velocity;
    ofVec2f force;
    float radious;
    float maxSpeed;
    
};

#endif /* defined(__opticalFlowApp1__particle__) */
particle.cpp

//
//  particle.cpp
//  opticalFlowApp1
//
//  Created by aa_debdeb on 2015/11/15.
//
//

#include "particle.h"

Particle::Particle(){
    position = ofVec2f(ofRandom(ofGetWidth()), ofRandom(ofGetHeight()));
    velocity = ofVec2f(ofRandom(-1, 1), ofRandom(-1, 1));
    force = ofVec2f(0, 0);
    radious = 10;
    maxSpeed = 10;
    
}

void Particle::update(){
    velocity *= 0.99;
    velocity += force;
    velocity.limit(maxSpeed);
    position += velocity;
    borders();
    force *= 0;
}

void Particle::borders(){
    if(position.x < radious){
        position.x = radious;
        velocity.x *= -1;
    }
    if(position.x > ofGetWidth() - radious){
        position.x = ofGetWidth() - radious;
        velocity *= -1;
    }
    if(position.y < radious){
        position.y = radious;
        velocity.y *= -1;
    }
    if(position.y > ofGetHeight() - radious){
        position.y = ofGetHeight() - radious;
        velocity.y *= -1;
    }
}

void Particle::draw(){
    ofSetColor(255, 255, 0, 100);
    ofDrawCircle(position.x, position.y, radious);
}

void Particle::serForce(ofVec2f _force){
    force = _force;
}

プロジェクトファイルは以下. openFrameworks/opticalFlowApp1 at master · aa-debdeb/openFrameworks

参考

Media Art II 2013 第6回:openFrameworks Addonを使う 2 - ofxOpenCV と ofxCv