今見てくれてる人の数

ホンキートンク・スーダラブルース

ゆるコラム、oF、邦ロックや歌謡曲、小説の感想。ドラクエ、JavaScript、ドラゴンボール超など。湘南あたりを転がってる石コロのゆるゆる生きてく超雑多な軌跡です。

【openFrameworks 冒険記10】ofxOpenCvで色々やってみる2!グレースケールのフレーム保存、現在との差分表示。

 今回はこれを作ります〜。

f:id:sudara_bluse:20171116174915p:plain

 

グレースケール映像任意のフレームで保存して描画!

現在との差分映像を表示!

のちの背景画像と比べて、輪郭の抽出や(いつか笑顔検知)への基礎です。

 

 

 

www.sudara-bluse.tokyo

 

前回の記事から追加された処置内容を説明します。

なのでまずは、そっちを読んでね。

 

 

実装内容(前回からの追記部分のみ)

下部のコメントつきソースを見ながらのがわかりやすいカモです。。

ofApp.hで

// グレースケールイメージで背景画像用(grayBase)と差分(grayDiff) インスタンスを定義

ofxCvGrayscaleImage grayBase;

ofxCvGrayscaleImage grayDiff;

// 保存したかどうかのフラグを定義

bool isSave;

 

ofApp.cppで

allocate()で前回みたいに、grayBaseとgrayDiffの処理するメモリ領域を確保

isSave = true;    // 保存したかどうかのフラグを初期化

grayBase に現在の画像 grayImg をコピー。 (isSave == true の時のみ)


↑これを本当は綺麗に輪郭とる為に真っ白バックの場所などでやる


grayDiff.absDiff(grayBase, grayImg); で

grayDiffにgrayBaseとgrayImgの差分を格納。

draw

 

 

ofApp.h
#pragma once

#include "ofMain.h"
#include "ofxOpenCv.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 cam;

    // カメラから入った1フレーム分の画像
    ofxCvColorImage colorImg;

    // カメラから入った1フレーム分のグレースケールの画像
    ofxCvGrayscaleImage grayImg;

    // グレースケールのイメージで現在と差分
    ofxCvGrayscaleImage grayBase;
    ofxCvGrayscaleImage grayDiff;

    // 保存したかどうかのフラグ
    bool isSave;

};

ofApp.cpp
#include "ofApp.h"

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

    // カメラからの取り込み
    cam.initGrabber(320, 240);

    // カラー画像を格納する領域を確保
    colorImg.allocate(320, 240);
    // グレースケール画像を格納する領域
    grayImg.allocate(320, 240);

    // 現在と差分の領域も確保
    grayBase.allocate(320, 240);
    grayDiff.allocate(320, 240);

    // 保存したかどうか
    isSave = true;


}

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

    // カメラの更新
    cam.update();

    // 一個一個のピクセルデータをカラーイメージに格納する
    colorImg.setFromPixels(cam.getPixels().getData(), 320, 240);
    colorImg.mirror(false, true);

    // グレースケールイメージにカラーデータを入れる
    grayImg = colorImg;


    // isSaveがtrueだった元画像に現在のグレーイメージを入れる
    if(isSave == true){
        grayBase = grayImg;
        // 撮影したらfalseにして、もう一度キーを押さない限りは背景画像は撮影されないようにする        
        isSave = false;
    }


    // grayBase, grayImgの差分を求めてgrayDiffにセット
    grayDiff.absDiff(grayBase, grayImg);


    // 二値化 (あとで輪郭抽出の時に白黒はっきりさせる)
    //grayDiff.threshold(100);


}

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

    colorImg.draw(0,0, 320, 240);
    grayImg.draw(330,0, 320, 240);


    grayBase.draw(0,250, 320, 240);
    grayDiff.draw(330, 250, 320, 240);

}

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

    // スペースキーを押す事によってフレームを保存
    if(key == ' '){
        isSave = true;
    }

}

 

うーんgrayDiff.absDiff(grayBase, grayImg);の挙動が引っかかる。

こういうもんなのかな。そこ以外はわかる。

なんとなく理解。輪郭とったらわかるかな。

 

ちょいむずですがメディアアートっぽいですね。

 次は輪郭頑張るぞ!