Skip to content

Instantly share code, notes, and snippets.

@boxysean
Created March 6, 2014 20:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boxysean/9398839 to your computer and use it in GitHub Desktop.
Save boxysean/9398839 to your computer and use it in GitHub Desktop.
#include "ofApp.h"
void ofApp::writejacks(int jacks) {
ofFile file(ofToDataPath("DocumentRoot/jumpingjacks.tmp"), ofFile::WriteOnly);
file << jacks/2;
file.close();
ofFile::moveFromTo(ofToDataPath("DocumentRoot/jumpingjacks.tmp"),ofToDataPath("DocumentRoot/jumpingjacks"), true, true);
}
void ofApp::writecalibrated(int calibrated) {
ofFile file(ofToDataPath("DocumentRoot/calibrated.tmp"), ofFile::WriteOnly);
file << calibrated;
file.close();
ofFile::moveFromTo(ofToDataPath("DocumentRoot/calibrated.tmp"),ofToDataPath("DocumentRoot/calibrated"), true, true);
}
void ofApp::setup(){
ofSetLogLevel(OF_LOG_VERBOSE);
calibrated = false;
lerp = 0.50;
fullscreen = false;
bAutodepth = false;
bReset = false;
threshold = 0.60;
starting_column_percent = 0.60;
latchWidth = 0.10;
playerheight = 0;
jacks = 0;
bJumpingJack = false;
lastCalibrationCheckSeconds = 0;
range_0_0 = 0.0;
range_0_1 = 0.2;
range_1_0 = 0.1;
range_1_1 = 0.3;
range_2_0 = 0.3;
range_2_1 = 1.0;
maxAreaThreshold = threshold + latchWidth;
minAreaThreshold = threshold - latchWidth;
dimager.setup();
setup_image_buffers();
setup_http_server();
ofSetFrameRate(30);
dimager.changeOperatingFrequency(3);
dimager.roiRect.x = 0;
dimager.roiRect.y = 0;
dimager.roiRect.width = 159;
dimager.roiRect.height = 119;
dimager.nearThreshold = 2.5;
dimager.farThreshold = 150;
int max_size = 160*120;
dimager.minBlobSize = 0.02;
dimager.maxBlobSize = 1.0;
dimager.bAutoReconnect = true;
setup_gui();
}
void ofApp::setup_image_buffers() {
video_height = 120;
video_width = 160;
cout << "h X w = " << video_height << " x " << video_width << endl;
}
void ofApp::setup_gui(){
gui = new ofxUICanvas(0, 0, 300, ofGetHeight());
gui->addLabel("WOW SETTINGS");
gui->addButton( "RESET" , &bReset );
gui->addLabel("ANALOG > DIGITALS");
gui->addSlider("POINTY TEETH", 0.0, 1.0, &lerp);
gui->addSlider("WOW THRESHOLD", 0.0, 0.5, &latchWidth);
gui->addLabel("CALIBRATING");
gui->addRangeSlider("col0", 0.0, 1.0, &range_0_0, &range_0_1);
gui->addRangeSlider("col1", 0.0, 1.0, &range_1_0, &range_1_1);
gui->addRangeSlider("col2", 0.0, 1.0, &range_2_0, &range_2_1);
gui->addLabel("CAMERA");
dimager.setupGUI(gui);
ofAddListener(gui->newGUIEvent,this,&ofApp::guiEvent);
myFont.loadFont("fonts/8-BIT WONDER.ttf", 24, true, true, true);
}
void ofApp::setup_http_server() {
server = ofx::HTTP::BasicPostServer::makeShared();
server->getPostRoute()->registerPostEvents(this);
server->start();
}
bool ofApp::onHTTPFormEvent(ofx::HTTP::HTTPFormEventArgs& args)
{
if(args.getRequestContentLength() > 4){
calibrated = false;
} else {
jacks = 0;
calibrated = true;
writejacks(jacks);
}
return true;
}
void ofApp::update(){
dimager.update();
if(jacks < 300) {
if (bReset){
jacks = 0;
playerheight = 0;
}
if(bAutodepth){
int max_samples=3;
short depth=0;
for(int samples=0; samples<max_samples; samples++){
depth += dimager.depthBuffer[(160*120-max_samples)/2+samples];
}
depth /= max_samples;
dimager.nearThreshold = depth - 10;
dimager.farThreshold = depth + 15;
printf("autoranging depth to %d -> %d\n", dimager.nearThreshold, dimager.farThreshold);
}
if(!(ofGetFrameNum() % 10)){
int pixel=0;
column_percents[0] = 0;
column_percents[1] = 0;
column_percents[2] = 0;
for (int r = 0; r < 120; r++) {
int colIdx = r / 40;
for (int c = 0; c < 160; c++) {
int pixIdx = r * 160 + c;
if(dimager.grayBlobs.getPixels()[pixIdx] & (1<<7) != 0){
column_percents[colIdx]++;
}
}
}
for(int i = 0; i<3; i++){
column_percents[i] /= 6400.;
}
maxAreaThreshold = threshold * column_percents[2] / starting_column_percent + latchWidth;
minAreaThreshold = threshold * column_percents[2] / starting_column_percent - latchWidth;
if(!calibrated){
if( column_percents[0] > range_0_0 && column_percents[0] < range_0_1
&& column_percents[1] > range_1_0 && column_percents[1] < range_1_1
&& column_percents[2] > range_2_0 && column_percents[2] < range_2_1)
{
writecalibrated(1);
} else {
writecalibrated(0);
}
}
}
if(dimager.contourFinder.nBlobs > 0){
playerheight_normalized = dimager.contourFinder.blobs[0].boundingRect.height / video_height;
float armwidth_normalized = dimager.contourFinder.blobs[0].boundingRect.width / video_width;
if(playerheight==0){
playerheight=playerheight_normalized;
}
if(widths.size()==0){
widths.push_back(playerheight_normalized);
} else {
// YO THIS IS BECAUSE WE ARE ROTATED YO
widths.push_back(ofLerp(widths[widths.size()-1], playerheight_normalized, lerp));
}
if(widths.size() + (*gui->getRect()).width > ofGetWidth()) { widths.clear(); }
if(!bJumpingJack && playerheight_normalized > maxAreaThreshold) {
latchColor = ofColor::green;
bJumpingJack = true;
}
if(bJumpingJack && playerheight_normalized < minAreaThreshold) {
latchColor = ofColor::yellow;
bJumpingJack = false;
std::cout << jacks++ << " jacks" << endl;
writejacks(jacks);
}
}
}
}
void ofApp::draw(){
ofSetColor( 255 ) ;
dimager.draw( 330 , 15 ) ;
int gui_width = (*gui->getRect()).width;
float spacing = 1.2;
int header_offset = 20;
ofSetColor(ofColor::white);
myFont.drawStringAsShapes(ofToString(jacks/2) + " jacks", ofGetWidth()-300, 50);
width_line.clear();
for(int i=0; i<widths.size(); i++) {
width_line.addVertex(ofVec2f((float)i + (*gui->getRect()).width, ofGetHeight() - 400. * widths[i]));
}
ofSetColor(latchColor);
width_line.draw();
if(!calibrated){
ofDrawBitmapStringHighlight(ofToString(column_percents[0]), ofGetWidth()-100, 400);
ofDrawBitmapStringHighlight(ofToString(column_percents[1]), ofGetWidth()-100, 440);
ofDrawBitmapStringHighlight(ofToString(column_percents[2]), ofGetWidth()-100, 480);
}
ofSetColor(ofColor::red);
ofLine(gui_width, ofGetHeight() - 400. * maxAreaThreshold, ofGetWidth(), ofGetHeight() - 400. * maxAreaThreshold);
ofSetColor(ofColor::blue);
ofLine(gui_width, ofGetHeight() - 400. * minAreaThreshold, ofGetWidth(), ofGetHeight() - 400. * minAreaThreshold);
}
void ofApp::keyPressed(int key){
switch (key){
case 'f':
fullscreen = ! fullscreen;
ofSetFullscreen(fullscreen);
break;
case 'g':
gui->toggleVisible();
break;
}
}
void ofApp::guiEvent(ofxUIEventArgs &e){
string name = e.widget->getName();
int kind = e.widget->getKind();
if ( name == "DEPTH RANGE" )
{
ofxUIRangeSlider * slider = (ofxUIRangeSlider*)e.widget ;
dimager.nearThreshold = slider->getScaledValueLow() ;
dimager.farThreshold = slider->getScaledValueHigh() ;
}
if ( name == "BLOB SIZE RANGE" )
{
ofxUIRangeSlider * slider = (ofxUIRangeSlider*)e.widget ;
int maxPixels= 160 * 120 ;
dimager.maxBlobSize = slider->getScaledValueHigh() * maxPixels ;
dimager.minBlobSize = slider->getScaledValueLow() * maxPixels ;
}
if ( name == "BLOBS BLUR" )
{
ofxUISlider * slider = ( ofxUISlider* )e.widget ;
int _blurAmount = (int)slider->getScaledValue() ;
if ( _blurAmount % 2 == 0 )
_blurAmount++ ;
dimager.grayBlobsBlurAmount = _blurAmount ;
}
//Change the Threshold settings
if ( name == "DEPTH THRESHOLD" || name == "GRAYSCALE THRESHOLD" )
{
dimager.changeHardwareThresholds( dimager.grayscaleThreshold , dimager.depthThreshold ) ;
}
if ( name == "IR FREQUENCY" )
{
ofxUISlider * slider = ( ofxUISlider* )e.widget ;
int val = (int)slider->getScaledValue() ;
dimager.changeOperatingFrequency( val ) ;
}
}
#pragma once
#include "ofMain.h"
#include "ofxOpenCV.h"
#include "ofxUI.h"
#include "ofTrueTypeFont.h"
#include "ofMath.h"
#include "ofxHTTP.h"
#include "ofxDImager.h"
class ofApp : public ofBaseApp {
private:
void setup_image_buffers();
void setup_gui();
void setup_http_server();
void writejacks(int jacks);
void writecalibrated(int calibrated);
bool fullscreen;
public:
void setup();
void update();
void draw();
void keyPressed(int key);
ofxDImager dimager;
bool bJumpingJack, bReset;
int jacks;
float minAreaThreshold, maxAreaThreshold;
float video_height, video_width;
float lerp; // how much to interpolate
bool bAutodepth; // automatically change the depth range
int playerheight;
int lastCalibrationCheckSeconds;
float playerheight_normalized;
bool calibrated;
float column_percents[3];
float starting_column_percent, threshold, latchWidth;
float range_0_0, range_0_1, range_1_0, range_1_1, range_2_0, range_2_1;
ofTrueTypeFont myFont;
vector<float> widths;
ofPolyline width_line;
ofColor latchColor;
ofxUICanvas *gui;
void guiEvent(ofxUIEventArgs &e);
ofx::HTTP::BasicPostServer::SharedPtr server;
bool onHTTPFormEvent(ofx::HTTP::HTTPFormEventArgs& args);
bool onHTTPRawFormEvent(ofx::HTTP::HTTPRawFormEventArgs& args){return false;};
bool onHTTPUploadStartedEvent(ofx::HTTP::HTTPUploadEventArgs& args){return false;};
bool onHTTPUploadProgressEvent(ofx::HTTP::HTTPUploadEventArgs& args){return false;};
bool onHTTPUploadFinishedEvent(ofx::HTTP::HTTPUploadEventArgs& args){return false;};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment