カメラ画像をofxVideoGrabberで取得してofxTurboJpegでエンコードして、ofxZMQを通してネットワーク配信するプログラムサンプル
OpenCVを使わずに、openFrameworksのアドオンだけで動くように変更しました。
ofxZmq
GitHub - satoruhiga/ofxZmq
の2つのアドオンを使用しています。
今回はopenCV版とは違いofxZmqの改造は不要ですが、ofxTurboJpegのsave関数がprivateで定義されているのをpublicに変更してやる必要があります。(なんでprivateにされてるんだろう??)
ofApp.h
#pragma once #include "ofMain.h" #include "ofxTurboJpeg.h" class ofxZmqSubscriber; class ofxZmqPublisher; 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 windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); ofxZmqSubscriber* subscriber; ofxZmqPublisher* publisher; ofVideoGrabber cap; ofxTurboJpeg turbo; ofImage frame; ofBuffer send_buf; int params; ofImage image; ofBuffer recv_buf; };
ofApp.cpp
#include "ofApp.h" #include "ofxZmq.h" //-------------------------------------------------------------- void ofApp::setup() { ofSetFrameRate(30); cap.setVerbose(true); cap.setDeviceID(1); if (cap.initGrabber(640, 480)) { //frame.allocate(cap.getWidth(), cap.getHeight(), OF_IMAGE_COLOR); params = 90; // quality // start server publisher = new ofxZmqPublisher(); publisher->setHighWaterMark(1); publisher->bind("tcp://*:9999"); } // start client subscriber = new ofxZmqSubscriber(); subscriber->setHighWaterMark(1); subscriber->connect("tcp://localhost:9999"); } //-------------------------------------------------------------- void ofApp::update() { while (subscriber->hasWaitingMessage()) { subscriber->getNextMessage(recv_buf); turbo.load(image, recv_buf); // turbo.load(recv_buf, image); 2022/08/27 updated cout << "received data: " << recv_buf.size() << endl; } cap.update(); if (cap.isFrameNew()) { //frame = cap.getPixels(); turbo.save(send_buf, cap.getPixelsRef(), 90); publisher->send(send_buf); } } //-------------------------------------------------------------- void ofApp::draw() { cap.draw(0, 0); image.draw(cap.getWidth(), 0); } //-------------------------------------------------------------- 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::windowResized(int w, int h){ } //-------------------------------------------------------------- void ofApp::gotMessage(ofMessage msg){ } //-------------------------------------------------------------- void ofApp::dragEvent(ofDragInfo dragInfo){ }
その受信をofThread版。lock()しないで落ちないから書いてないけど、大丈夫かな。。。
ofApp.h
#pragma once #include "ofMain.h" #include "ofxTurboJpeg.h" class ofxZmqSubscriber; class ofxZmqPublisher; class ThreadedSubscriber : public ofThread { public: ThreadedSubscriber(ofxZmqSubscriber* ptr) : subscriber(ptr) { image.setUseTexture(true); } void threadedFunction(); ofImage& getImage(); protected: ofxZmqSubscriber* subscriber; ofxTurboJpeg turbo; ofBuffer recv_buf; ofImage image; }; 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 windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); ofxZmqSubscriber* subscriber; ofxZmqPublisher* publisher; ofVideoGrabber cap; ofxTurboJpeg turbo; ofImage frame; ofBuffer send_buf; int params; ThreadedSubscriber* threadedSubscriber; ofImage image; };
ofApp.cpp
#include "ofApp.h" #include "ofxZmq.h" void ThreadedSubscriber::threadedFunction() { while (isThreadRunning()) { while (subscriber->hasWaitingMessage()) { do { subscriber->getNextMessage(recv_buf); } while (subscriber->hasWaitingMessage()); turbo.load(recv_buf, image); image.update(); //image.saveImage("test.jpg"); cout << "received data: " << recv_buf.size() << "\r"; } } } ofImage& ThreadedSubscriber::getImage() { return image; } //-------------------------------------------------------------- void ofApp::setup() { ofSetFrameRate(30); cap.setVerbose(true); cap.setDeviceID(1); if (cap.initGrabber(640, 480)) { params = 90; // quality // start server publisher = new ofxZmqPublisher(); publisher->setHighWaterMark(1); publisher->bind("tcp://*:9999"); } // start client subscriber = new ofxZmqSubscriber(); subscriber->setHighWaterMark(1); subscriber->connect("tcp://localhost:9999"); threadedSubscriber = new ThreadedSubscriber(subscriber); threadedSubscriber->startThread(false); } //-------------------------------------------------------------- void ofApp::update() { cap.update(); if (cap.isFrameNew()) { //frame = cap.getPixels(); turbo.save(send_buf, cap.getPixelsRef(), 100); publisher->send(send_buf); } } //-------------------------------------------------------------- void ofApp::draw() { cap.draw(0, 0); image = threadedSubscriber->getImage(); image.draw(cap.getWidth(), 0); } //-------------------------------------------------------------- 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::windowResized(int w, int h){ } //-------------------------------------------------------------- void ofApp::gotMessage(ofMessage msg){ } //-------------------------------------------------------------- void ofApp::dragEvent(ofDragInfo dragInfo){ }
ofxZmq作者の方のサンプルの方が勉強になりそうです。
github.com
今日のハイスピードカメラ
CASIO EX-100Proが一台あると、実験に便利そうです。でも流通が限定していて入手しづらいうえに高い。一般向けのこれで妥協するかどうか。
とか、思っていたら断然こっちの方がいいですね。新しいハイスピードカメラもっと調べてみよう。
カメラ画像をOpenCVで取得してJpegエンコードして、ZeroMQを通してネットワーク配信するプログラムサンプル(その2.受信をマルチスレッド化)
testApp.h
#pragma once #include "ofMain.h" #include "opencv2/opencv.hpp" class ofxZmqSubscriber; class ofxZmqPublisher; class ThreadedSubscriber : public ofThread { public: ThreadedSubscriber(ofxZmqSubscriber* ptr) : subscriber(ptr) {}; void threadedFunction(); void draw(); protected: ofxZmqSubscriber* subscriber; cv::Mat image; std::vector<unsigned char> recv_buf; }; class testApp : public ofBaseApp{ public: ~testApp(); 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 windowResized(int w, int h); void dragEvent(ofDragInfo dragInfo); void gotMessage(ofMessage msg); ofxZmqSubscriber* subscriber; ofxZmqPublisher* publisher; cv::VideoCapture cap; cv::Mat frame; std::vector<unsigned char> send_buf; std::vector<int> params; string type; ThreadedSubscriber* threadedSubscriber; };
testApp.cpp
#include "testApp.h" #include "ofxZmq.h" #include "opencv2/opencv.hpp" #pragma comment(lib, "opencv_calib3d310.lib") #pragma comment(lib, "opencv_core310.lib") #pragma comment(lib, "opencv_features2d310.lib") #pragma comment(lib, "opencv_flann310.lib") #pragma comment(lib, "opencv_highgui310.lib") #pragma comment(lib, "opencv_imgcodecs310.lib") #pragma comment(lib, "opencv_imgproc310.lib") #pragma comment(lib, "opencv_ml310.lib") #pragma comment(lib, "opencv_objdetect310.lib") #pragma comment(lib, "opencv_photo310.lib") #pragma comment(lib, "opencv_shape310.lib") #pragma comment(lib, "opencv_stitching310.lib") #pragma comment(lib, "opencv_superres310.lib") #pragma comment(lib, "opencv_ts310.lib") #pragma comment(lib, "opencv_video310.lib") #pragma comment(lib, "opencv_videoio310.lib") #pragma comment(lib, "opencv_videostab310.lib") void ThreadedSubscriber::threadedFunction() { while (isThreadRunning()) { while (subscriber->hasWaitingMessage()) { do { subscriber->getNextMessage(recv_buf); } while (subscriber->hasWaitingMessage()); lock(); image = cv::imdecode(recv_buf, CV_LOAD_IMAGE_COLOR); //image = buf.clone(); unlock(); cout << "received data: " << recv_buf.size() << endl; //sleep(1); } } } void ThreadedSubscriber::draw() { lock(); if (!image.empty()) { cv::imshow("received", image); } unlock(); } testApp::~testApp() { if (threadedSubscriber->isThreadRunning()) { threadedSubscriber->stopThread(); } subscriber->disconnect("tcp://localhost:9999"); cap.release(); } //-------------------------------------------------------------- void testApp::setup() { ofSetFrameRate(30); bool ret = cap.open(0); if (cap.isOpened()) { cout << "Camera is ready!" << endl; cap.set(cv::CAP_PROP_FRAME_WIDTH, 1280); cap.set(cv::CAP_PROP_FRAME_HEIGHT, 720); cap.set(cv::CAP_PROP_FPS, 30); //type = ".jpg"; type = ".webp"; if (type == ".jpg") { params.push_back(CV_IMWRITE_JPEG_QUALITY); params.push_back(100); params.push_back(CV_IMWRITE_JPEG_OPTIMIZE); params.push_back(0); params.push_back(CV_IMWRITE_JPEG_PROGRESSIVE); params.push_back(0); } else if (type == ".webp") { params.push_back(CV_IMWRITE_WEBP_QUALITY); params.push_back(70); } // start server publisher = new ofxZmqPublisher(); publisher->setHighWaterMark(1); publisher->bind("tcp://*:9999"); } // start client subscriber = new ofxZmqSubscriber(); subscriber->setHighWaterMark(0); subscriber->connect("tcp://localhost:9999"); //subscriber->connect("tcp://10.254.20.46:9999"); threadedSubscriber = new ThreadedSubscriber(subscriber); threadedSubscriber->startThread(true, false); } //-------------------------------------------------------------- void testApp::update() { if (!cap.isOpened()) return; if (cap.grab()) { bool res = cap.read(frame); if (res) { int msec_start = ofGetElapsedTimeMillis(); bool ret = cv::imencode(type, frame, send_buf, params); int msec_stop = ofGetElapsedTimeMillis(); if (ret) { publisher->send(send_buf); int lap = msec_stop - msec_start; int fps = (lap) ? 1000.0 / lap : ofGetFrameRate(); cout << "encoded size(" << type << ") : " << send_buf.size() << ", time : " << lap << ", fps : " << fps << endl; } } } } //-------------------------------------------------------------- void testApp::draw() { threadedSubscriber->draw(); } //-------------------------------------------------------------- void testApp::keyPressed(int key) { if (threadedSubscriber->isThreadRunning()) { threadedSubscriber->stopThread(); subscriber->disconnect("tcp://localhost:9999"); subscriber->connect("tcp://localhost:9999"); threadedSubscriber->startThread(true, false); } } //-------------------------------------------------------------- void testApp::keyReleased(int key) { } //-------------------------------------------------------------- void testApp::mouseMoved(int x, int y) { } //-------------------------------------------------------------- void testApp::mouseDragged(int x, int y, int button) { } //-------------------------------------------------------------- void testApp::mousePressed(int x, int y, int button) { } //-------------------------------------------------------------- void testApp::mouseReleased(int x, int y, int button) { } //-------------------------------------------------------------- void testApp::windowResized(int w, int h) { } //-------------------------------------------------------------- void testApp::gotMessage(ofMessage msg) { } //-------------------------------------------------------------- void testApp::dragEvent(ofDragInfo dragInfo) { }
今日の理想のリビングアイテム
テレビは、4Kなど映像のクオリティはうなぎのぼりで良くなっていますが、音響がついて行っていません。音と映像は、クオリティの均衡がとれてないとお互いの足を引っ張ってしまいますので、良い映像には良い音響が必要です。ヤマハのテレビ台型サラウンドスピーカーはかなり良いです。台の間が狭いので、高さのある機器を置けないのは減点ですが。色は黒と茶の2色ありますが、ヤマハは黒に限ります。
ヤマハ シアターラック50型まで対応YAMAHA YRS-1500-B
- 出版社/メーカー: ヤマハ
- メディア: エレクトロニクス
- この商品を含むブログを見る
ヤマハ 壁寄せ金具 (1台) ブラック YTS-V1200(B)
- 出版社/メーカー: ヤマハ
- 発売日: 2010/10/31
- メディア: エレクトロニクス
- この商品を含むブログを見る
ソニー 地上・BS・110度CSデジタルハイビジョン液晶テレビ BRAVIA X8500C 55V型 KJ-55X8500C
- 出版社/メーカー: ソニー
- 発売日: 2015/07/04
- メディア: エレクトロニクス
- この商品を含むブログを見る
ofxFaceTrackerで遊んでみる
(メモ)
オリジナルソース
github.com
FaceTrackerのオリジナル論文の解説
d.hatena.ne.jp
Visual Studioでのインストール時の修正
C/C++->OUTPUT Objects: $(IntDir)/%(RelativeDir)/
forum.openframeworks.cc
顔の置き換え
github.com
マルチフェイストラッキング
github.com
顔パーツのモデル
blog.kidapu.com
サンプル解説楽しいことをしたい: 【openframeworks】ofxFaceTrackerで遊んでみた。サンプル解説
応用例1:顔で制御、応用例2:顔を交換
yoppa.org
ライオンマスク
www.honeycomb-lab.co.jp
マンガの吹き出し
http://hackist.jp/?p=2979hackist.jp
インタラクティブアート
http://nickhardeman.com/tag/ofxfacetracker/nickhardeman.com
顔を楽器
http://golancourses.net/2014/haris/02/06/face-wah-wah-using-ofxfacetracker-and-ofxmidi/golancourses.net
講義資料
http://nakayasu.com/lecture/openframeworks-facetracker/6770nakayasu.com
SMILE to SMILE
www.bbmedia.co.jp
口から煙
http://ryujiyoshida.com/blog/category/studyryujiyoshida.com
顔のモーフィング
labs.1-10.com
カラオケ顔変換
http://www.kazushi.info/wp-content/uploads/2015/09/433149.pdf
MacOSXでの修正点
ryotakatoh.hatenablog.com
Twitterのハッシュ宅ofxtracker
twitter.com
AAM関連
AAMのモデル生成
qiita.com
http://www.mega.t-kougei.ac.jp/media/moriyama/projects/esa-aam.htmwww.mega.t-kougei.ac.jp
顔認識技術動向
d.hatena.ne.jp
今日の睡眠
シングルベッドに最低限必要な3点セットで6万円.ただのスポンジのくせに高いよなー.
東京西川 [エアー01] マットレス シングル ベーシック グレー
- 出版社/メーカー: AIR
- メディア: ホーム&キッチン
- クリック: 18回
- この商品を含むブログを見る
東京西川 枕 [エアー3D] コンディショニングピロー 高め スウィート グレー
- 出版社/メーカー: AIR
- メディア: ホーム&キッチン
- この商品を含むブログを見る
hiro_handleをpyzmq経由で呼び出せるようにする
(作業メモ)
まずOpenRTM-aistをPython2.7.10環境で構築しなおします。
python2.6はサポートが終了してしまうようで、pipを使ってpyzmqをすんなりインストールすることができません。
http://www.openrtm.org/openrtm/node/5768
32bit用 Windows用インストーラ OpenRTM-aist-Python_1.1.0-RELEASE_x86.msi
Python-2.7 python-2.7.10.msi
をダウンロードしてインストールします。Python2.7.11では駄目だそうです。
JointDataTypes.idlの追加
この節は使わないので、すっ飛ばしてもかまいません。
OpenRTM-aist-Python_1.1.0.zipを解凍して,setup.pyを編集します。
C:\workspace\OpenRTM-aist-Python-1.1.0\OpenRTM_aist\RTM_IDLの下にJointDataTypes.idlをコピーして追加します。
JointDataTypes.idlは,HIROのgrx/share/hpsys/idlにある。
.. baseidl_files = [ "BasicDataType.idl", "DataPort.idl", "ExtendedDataTypes.idl", "InterfaceDataTypes.idl", "Manager.idl", "OpenRTM.idl", "RTC.idl", "SDOPackage.idl", "JointDataTypes.idl" # added ] ..
そのあと、
python setup.py build
python setup.py install
をする。
cd OpenRTM_aist\RTM_IDL
してから、
omniidl -bpython JointDataTypes.idl
あとは普通にhiro_handleをインストール
pyzmqのインストール
pip install --upgrade pip
pip install pyzmq-static
カメラキャリブレーションのための自動撮影機能を背景差分を使って作る
動体検知をして、動いたものを見つけた後、一定時間画面に変化がないとシャッターを切ります。
単純な閾値処理しかしていませんが、結構ちゃんと動きます。
ただし、閾値がカメラ解像度に依存する上に、閾値の設定次第で使いやすさがまるで変ってしまいますが。
OpenFrameworks9.3とOpenCV3.1を使っています。
ofxGuiアドオンとofxHistoryPlot( GitHub - armadillu/ofxHistoryPlot: Visualize value history on a configurable graph )も使います。
ofApp.h
#pragma once #include "ofMain.h" #include "ofxGui.h" #include "ofxHistoryPlot.h" #include "opencv2/opencv.hpp" 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); cv::Mat frame; cv::Mat fgMask; cv::Mat bgMask; cv::Ptr<cv::BackgroundSubtractorMOG2> pMOG2; cv::VideoCapture cap; ofxPanel gui; ofxFloatSlider background_ratio; ofxFloatSlider complexity_reduction_threshold; ofxToggle shadow_detection_flag; ofxIntSlider history; // the number of last frames that affect the background model ofxIntSlider nMixtures; // the number of gaussian components in the background model ofxFloatSlider shadow_threshold; ofxIntSlider shadow_value; ofxFloatSlider varInit; // the initial variance of each gaussian component ofxFloatSlider varMax; ofxFloatSlider varMin; ofxFloatSlider varThreshold; // the variance threshold for the pixel - model match ofxFloatSlider varThresholdGen; // the variance threshold for the pixel - model match used for new mixture component generation. void BackgroundRatioChanged(float& value) { pMOG2->setBackgroundRatio(value); } void ComplexityReductionThresholdChanged(float& value) { pMOG2->setComplexityReductionThreshold(value); } void ShadowDetectionFlagChanged(bool& value) { pMOG2->setDetectShadows(value); } void HistoryChanged(int & value) { pMOG2->setHistory(value); } void nMixturesChanged(int & value) { pMOG2->setNMixtures(value); } void ShadowThresholdChanged(float & value) { pMOG2->setShadowThreshold(value); } void ShadowValueChanged(int & value) { pMOG2->setShadowValue(value); } void VarInitChanged(float & value) { pMOG2->setVarInit(value); } void VarMaxChanged(float & value) { pMOG2->setVarMax(value); varMin.setMax(value); } void VarMinChanged(float & value) { pMOG2->setVarMin(value); varMax.setMin(value); } void VarThresholdChanged(float & value) { pMOG2->setVarThreshold(value); } void VarThresholdGenChanged(float & value) { pMOG2->setVarThresholdGen(value); } ofxHistoryPlot * plot; ofxPanel auto_shutter; ofxFloatSlider high_threshold; ofxFloatSlider low_threshold; int detection_state; void HighThresholdChanged(float & value) { low_threshold.setMax(value); } void LowThresholdChanged(float & value) { high_threshold.setMin(value); } vector<cv::Mat> calib; };
ofApp.cpp
#include "ofApp.h" #include "opencv2/opencv.hpp" #pragma comment(lib, "opencv_calib3d310.lib") #pragma comment(lib, "opencv_core310.lib") #pragma comment(lib, "opencv_features2d310.lib") #pragma comment(lib, "opencv_flann310.lib") #pragma comment(lib, "opencv_highgui310.lib") #pragma comment(lib, "opencv_imgcodecs310.lib") #pragma comment(lib, "opencv_imgproc310.lib") #pragma comment(lib, "opencv_ml310.lib") #pragma comment(lib, "opencv_objdetect310.lib") #pragma comment(lib, "opencv_photo310.lib") #pragma comment(lib, "opencv_shape310.lib") #pragma comment(lib, "opencv_stitching310.lib") #pragma comment(lib, "opencv_superres310.lib") #pragma comment(lib, "opencv_ts310.lib") #pragma comment(lib, "opencv_video310.lib") #pragma comment(lib, "opencv_videoio310.lib") #pragma comment(lib, "opencv_videostab310.lib") //-------------------------------------------------------------- void ofApp::setup() { cap.open(1); cap.set(cv::CAP_PROP_FRAME_WIDTH, 1280); cap.set(cv::CAP_PROP_FRAME_HEIGHT, 720); if (!cap.isOpened()) { cout << "Can't open the camera" << endl; ofExit(); } cap >> frame; int initHistory = 200; float initVarThreshold = 16; bool bShadowDetection = true; pMOG2 = cv::createBackgroundSubtractorMOG2(initHistory, initVarThreshold, bShadowDetection); pMOG2->setVarThreshold(10); gui.setup("settings", "settings.xml", 10, 10); gui.add(background_ratio.setup("background ratio", pMOG2->getBackgroundRatio(), 0.0, 1.0)); gui.add(complexity_reduction_threshold.setup("complexity reduction", pMOG2->getComplexityReductionThreshold(), 0.0, 1.0)); gui.add(shadow_detection_flag.setup("shadow detection flag", pMOG2->getDetectShadows())); gui.add(history.setup("hisotry", pMOG2->getHistory(), 1, 1000)); gui.add(nMixtures.setup("nMixtures", pMOG2->getNMixtures(), 1, 100)); gui.add(shadow_threshold.setup("shadow threshold", pMOG2->getShadowThreshold(), -1.0, 1.0)); gui.add(varInit.setup("varInit", pMOG2->getVarInit(), 0.0, 100.0)); gui.add(varMax.setup("varMax", pMOG2->getVarMax(), pMOG2->getVarMin(), 10000.0)); gui.add(varMin.setup("varMin", pMOG2->getVarMin(), 0.0, pMOG2->getVarMax())); gui.add(varThreshold.setup("varThreshold", pMOG2->getVarThreshold(), 0.0, 10000.0)); gui.add(varThresholdGen.setup("varThresholdGen", pMOG2->getVarThresholdGen(), 0.0, 10000.0)); background_ratio.addListener(this, &ofApp::BackgroundRatioChanged); complexity_reduction_threshold.addListener(this, &ofApp::ComplexityReductionThresholdChanged); shadow_detection_flag.addListener(this, &ofApp::ShadowDetectionFlagChanged); history.addListener(this, &ofApp::HistoryChanged); nMixtures.addListener(this, &ofApp::nMixturesChanged); shadow_threshold.addListener(this, &ofApp::ShadowThresholdChanged); varInit.addListener(this, &ofApp::VarInitChanged); varMax.addListener(this, &ofApp::VarMaxChanged); varMin.addListener(this, &ofApp::VarMinChanged); varThreshold.addListener(this, &ofApp::VarThresholdChanged); varThresholdGen.addListener(this, &ofApp::VarThresholdGenChanged); // History Plot int numSamples = 350; plot = new ofxHistoryPlot(NULL, "Ratio", numSamples, false); //NULL cos we don't want it to auto-update. confirmed by "true" plot->setRange(0, 10000.f / sqrt(frame.cols * frame.rows) ); //hard range, will not adapt to values off-scale plot->addHorizontalGuide(ofGetHeight() / 2, ofColor(255, 0, 0)); //add custom reference guides plot->setColor(ofColor(0, 255, 0)); //color of the plot line plot->setShowNumericalInfo(true); //show the current value and the scale in the plot plot->setRespectBorders(true); //dont let the plot draw on top of text plot->setLineWidth(1); //plot line width plot->setBackgroundColor(ofColor(0, 220)); //custom bg color //custom grid setup plot->setDrawGrid(true); plot->setGridColor(ofColor(30)); //grid lines color plot->setGridUnit(14); plot->setCropToRect(true); normalize_ratio = 1.0f / sqrt(frame.cols*frame.rows); auto_shutter.setup("shutter"); auto_shutter.add(high_threshold.setup("high", 3200.f * normalize_ratio, 1800.f * normalize_ratio, 10000.f * normalize_ratio)); auto_shutter.add(low_threshold.setup("low", 1800.f * normalize_ratio, 0, high_threshold)); high_threshold.addListener(this, &ofApp::HighThresholdChanged); low_threshold.addListener(this, &ofApp::LowThresholdChanged); detection_state = 0; } //-------------------------------------------------------------- void ofApp::update() { if (cap.grab()) { cap >> frame; pMOG2->apply(frame, fgMask); pMOG2->getBackgroundImage(bgMask); cv::Scalar v = cv::sum(fgMask); plot->update(sqrt(v[0]) * normalize_ratio); if (detection_state == 0) { if (sqrt(v[0]) * normalize_ratio > high_threshold) { detection_state = 1; } } else if (detection_state == 1) { if (sqrt(v[0]) * normalize_ratio < low_threshold) { detection_state = 0; calib.push_back(cv::Mat()); frame.copyTo(calib.back()); cv::imshow("calib", calib.back()); cout << "calib" << std::to_string(calib.size()) << endl; } } } } //-------------------------------------------------------------- void ofApp::draw() { if (!fgMask.empty()) { cv::imshow("FG", fgMask); } if (!bgMask.empty()) { cv::imshow("BG", bgMask); } gui.draw(); plot->draw(220, 10, 640, 240); } //-------------------------------------------------------------- void ofApp::keyPressed(int key) { if (key == 's') { int cameraIdx = 0; for (int i = 0; i < calib.size(); i++) { stringstream ss; ss << to_string(cameraIdx) << '-' << /* std::setw(3) << std::setfill('0') <<*/ i << ".png"; imwrite(ss.str(), calib[i]); cout << "wrote " << ss.str() << endl; } } } //-------------------------------------------------------------- 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) { }
本日の防災
乾電池はある程度手元にないと不安ですね。
- 出版社/メーカー: AmazonBasics
- メディア: ヘルスケア&ケア用品
- この商品を含むブログを見る
- 出版社/メーカー: AmazonBasics
- メディア: ヘルスケア&ケア用品
- この商品を含むブログを見る
(メモ)OpenCV3.1で背景差分MOG2を使う時のサンプル
createBackgroundSubtractorMOG2なる関数を使うようです。
ofApp.h
#pragma once #include "ofMain.h" #include "opencv2/opencv.hpp" 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); cv::Mat frame; cv::Mat fgMask; cv::Ptr<cv::BackgroundSubtractorMOG2> pMOG2; cv::VideoCapture cap; };
ofApp.cpp
#include "ofApp.h" #include "opencv2/opencv.hpp" #pragma comment(lib, "opencv_calib3d310.lib") #pragma comment(lib, "opencv_core310.lib") #pragma comment(lib, "opencv_features2d310.lib") #pragma comment(lib, "opencv_flann310.lib") #pragma comment(lib, "opencv_highgui310.lib") #pragma comment(lib, "opencv_imgcodecs310.lib") #pragma comment(lib, "opencv_imgproc310.lib") #pragma comment(lib, "opencv_ml310.lib") #pragma comment(lib, "opencv_objdetect310.lib") #pragma comment(lib, "opencv_photo310.lib") #pragma comment(lib, "opencv_shape310.lib") #pragma comment(lib, "opencv_stitching310.lib") #pragma comment(lib, "opencv_superres310.lib") #pragma comment(lib, "opencv_ts310.lib") #pragma comment(lib, "opencv_video310.lib") #pragma comment(lib, "opencv_videoio310.lib") #pragma comment(lib, "opencv_videostab310.lib") //-------------------------------------------------------------- void ofApp::setup(){ cap.open(1); if (!cap.isOpened()) { cout << "Can't open the camera" << endl; ofExit(); } int history = 500; float varThreshold = 16; bool bShadowDetection = true; pMOG2 = cv::createBackgroundSubtractorMOG2(history, varThreshold, bShadowDetection); pMOG2->setVarThreshold(10); } //-------------------------------------------------------------- void ofApp::update(){ if (cap.grab()) { cap >> frame; pMOG2->apply(frame, fgMask); } } //-------------------------------------------------------------- void ofApp::draw(){ if (!fgMask.empty()) { cv::imshow("MOG2", fgMask); } } //-------------------------------------------------------------- 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){ }
パラメータ調整GUI付きサンプル
#pragma once #include "ofMain.h" #include "ofxGui.h" #include "opencv2/opencv.hpp" 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); cv::Mat frame; cv::Mat fgMask; cv::Mat bgMask; cv::Ptr<cv::BackgroundSubtractorMOG2> pMOG2; cv::VideoCapture cap; ofxPanel gui; ofxFloatSlider background_ratio; ofxFloatSlider complexity_reduction_threshold; ofxToggle shadow_detection_flag; ofxIntSlider history; // the number of last frames that affect the background model ofxIntSlider nMixtures; // the number of gaussian components in the background model ofxFloatSlider shadow_threshold; ofxIntSlider shadow_value; ofxFloatSlider varInit; // the initial variance of each gaussian component ofxFloatSlider varMax; ofxFloatSlider varMin; ofxFloatSlider varThreshold; // the variance threshold for the pixel - model match ofxFloatSlider varThresholdGen; // the variance threshold for the pixel - model match used for new mixture component generation. void BackgroundRatioChanged(float& value) { pMOG2->setBackgroundRatio(value); } void ComplexityReductionThresholdChanged(float& value) { pMOG2->setComplexityReductionThreshold(value); } void ShadowDetectionFlagChanged(bool& value) { pMOG2->setDetectShadows(value); } void HistoryChanged(int & value) { pMOG2->setHistory(value); } void nMixturesChanged(int & value) { pMOG2->setNMixtures(value); } void ShadowThresholdChanged(float & value) { pMOG2->setShadowThreshold(value); } void ShadowValueChanged(int & value) { pMOG2->setShadowValue(value); } void VarInitChanged(float & value) { pMOG2->setVarInit(value); } void VarMaxChanged(float & value) { pMOG2->setVarMax(value); varMin.setMax(value); } void VarMinChanged(float & value) { pMOG2->setVarMin(value); varMax.setMin(value); } void VarThresholdChanged(float & value) { pMOG2->setVarThreshold(value); } void VarThresholdGenChanged(float & value) { pMOG2->setVarThresholdGen(value); } };
#include "ofApp.h" #include "opencv2/opencv.hpp" #pragma comment(lib, "opencv_calib3d310.lib") #pragma comment(lib, "opencv_core310.lib") #pragma comment(lib, "opencv_features2d310.lib") #pragma comment(lib, "opencv_flann310.lib") #pragma comment(lib, "opencv_highgui310.lib") #pragma comment(lib, "opencv_imgcodecs310.lib") #pragma comment(lib, "opencv_imgproc310.lib") #pragma comment(lib, "opencv_ml310.lib") #pragma comment(lib, "opencv_objdetect310.lib") #pragma comment(lib, "opencv_photo310.lib") #pragma comment(lib, "opencv_shape310.lib") #pragma comment(lib, "opencv_stitching310.lib") #pragma comment(lib, "opencv_superres310.lib") #pragma comment(lib, "opencv_ts310.lib") #pragma comment(lib, "opencv_video310.lib") #pragma comment(lib, "opencv_videoio310.lib") #pragma comment(lib, "opencv_videostab310.lib") //-------------------------------------------------------------- void ofApp::setup(){ cap.open(1); if (!cap.isOpened()) { cout << "Can't open the camera" << endl; ofExit(); } int initHistory = 500; float initVarThreshold = 16; bool bShadowDetection = true; pMOG2 = cv::createBackgroundSubtractorMOG2(initHistory, initVarThreshold, bShadowDetection); pMOG2->setVarThreshold(10); gui.setup("settings", "settings.xml", 10, 10); gui.add(background_ratio.setup("background ratio", pMOG2->getBackgroundRatio(), 0.0, 1.0)); gui.add(complexity_reduction_threshold.setup("complexity reduction", pMOG2->getComplexityReductionThreshold(), 0.0, 1.0)); gui.add(shadow_detection_flag.setup("shadow detection flag", pMOG2->getDetectShadows())); gui.add(history.setup("hisotry", pMOG2->getHistory(), 1, 1000)); gui.add(nMixtures.setup("nMixtures", pMOG2->getNMixtures(), 1, 100)); gui.add(shadow_threshold.setup("shadow threshold", pMOG2->getShadowThreshold(), -1.0, 1.0)); gui.add(varInit.setup("varInit", pMOG2->getVarInit(), 0.0, 100.0)); gui.add(varMax.setup("varMax", pMOG2->getVarMax(), pMOG2->getVarMin(), 10000.0)); gui.add(varMin.setup("varMin", pMOG2->getVarMin(), 0.0, pMOG2->getVarMax())); gui.add(varThreshold.setup("varThreshold", pMOG2->getVarThreshold(), 0.0, 10000.0)); gui.add(varThresholdGen.setup("varThresholdGen", pMOG2->getVarThresholdGen(), 0.0, 10000.0)); background_ratio.addListener(this, &ofApp::BackgroundRatioChanged); complexity_reduction_threshold.addListener(this, &ofApp::ComplexityReductionThresholdChanged); shadow_detection_flag.addListener(this, &ofApp::ShadowDetectionFlagChanged); history.addListener(this, &ofApp::HistoryChanged); nMixtures.addListener(this, &ofApp::nMixturesChanged); shadow_threshold.addListener(this, &ofApp::ShadowThresholdChanged); varInit.addListener(this, &ofApp::VarInitChanged); varMax.addListener(this, &ofApp::VarMaxChanged); varMin.addListener(this, &ofApp::VarMinChanged); varThreshold.addListener(this, &ofApp::VarThresholdChanged); varThresholdGen.addListener(this, &ofApp::VarThresholdGenChanged); } //-------------------------------------------------------------- void ofApp::update(){ if (cap.grab()) { cap >> frame; pMOG2->apply(frame, fgMask); pMOG2->getBackgroundImage(bgMask); } } //-------------------------------------------------------------- void ofApp::draw(){ if (!fgMask.empty()) { cv::imshow("FG", fgMask); } if(!bgMask.empty()) { cv::imshow("BG", bgMask); } 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のofxGuiとofParameterの仕様が変わってしまい、とても使いにくくなっていますね。
Qtでもあった現象ですが、綺麗にプログラムが書ける人がライブラリを書き直すと、プログラム的には美しくしくても使いづらい関数が続発するという悲しい事態に陥ります。方言を許容したまま開発を進めてほしいものです。
[1] OpenCV: segment_objects.cpp
今日の防災
Kindle版無料だそうですから、ダウンロードして一読しておくのが良いですね。
- 出版社/メーカー: 東京都
- 発売日: 2016/03/30
- メディア: Kindle版
- この商品を含むブログ (3件) を見る
簡易トイレも買っておいた方が良いでしょうか。
サッと固まる非常用トイレ袋(30回分) 災害での断水時でもトイレが使える!
- 出版社/メーカー: ブレイン(BRAIN)
- メディア: ホーム&キッチン
- 購入: 7人 クリック: 27回
- この商品を含むブログ (4件) を見る
openframeworksでネットワーク同期の方法
(メモ)
anagmaさんのofxNetworkSync addonが便利です。
github.com
ofNetworkアドオンも使用しています。
ofxNetworkSyncServerとofxNetworkSyncClientを同時に起動すると、
右耳と左耳で同期して音がなるので同期を確認することができます。
Kindle Oasis Wi-Fi + 3G バッテリー内蔵レザーカバー付属 ブラック キャンペーン情報つきモデル
- 出版社/メーカー: Amazon
- 発売日: 2016/04/27
- メディア: エレクトロニクス
- この商品を含むブログ (1件) を見る