summaryrefslogtreecommitdiff
path: root/gui/src
diff options
context:
space:
mode:
authorTim Redfern <tim@getdrop.com>2018-02-03 02:01:09 +0000
committerTim Redfern <tim@getdrop.com>2018-02-03 02:01:09 +0000
commitf19740af946bd1faa6d364995b72b8a32e2315e3 (patch)
treefce87902192f5d6861e68c65116e52a031401525 /gui/src
parent645e8c6007bdacaf2f37019d871ce9d3281a280d (diff)
many changes
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/lineSegmenter.cpp71
-rw-r--r--gui/src/lineSegmenter.h22
-rw-r--r--gui/src/lineTransformer.cpp2
-rw-r--r--gui/src/lineTransformer.h2
-rw-r--r--gui/src/main.cpp2
-rw-r--r--gui/src/ofApp.cpp301
-rw-r--r--gui/src/ofApp.h55
7 files changed, 402 insertions, 53 deletions
diff --git a/gui/src/lineSegmenter.cpp b/gui/src/lineSegmenter.cpp
new file mode 100644
index 0000000..14f6e24
--- /dev/null
+++ b/gui/src/lineSegmenter.cpp
@@ -0,0 +1,71 @@
+ #include "lineSegmenter.h"
+
+const vector <ofPolyline> & lineSegmenter::getSegments(int num,float coverage, float phase){
+ //num - number of segments
+ //coverage - amount that each segment fills it's slot from 0-1
+ //phase - from 0-1
+
+ //if the path is closed, we can make a segment that crosses the end/beginning
+ //however we want to be able to deal with open paths
+
+/*
+
+segments 0...n - 1
+phase 0...1
+
+phase 0
+
+segment 0 is (0 -> coverage) / n
+segment n - 1 is ((0 -> coverage) + (n-1)) /n
+
+phase 1: has to be the loop target, it has to look identical
+
+segment 0 is (1 -> coverage) / n
+segment n - 1 is (1 - > coverage) + (n-1)
+
+*/
+
+
+ segments.clear();
+
+ for (int i=0;i<num;i++){
+ float startIndex=line.getIndexAtPercent((phase+i)/num); //always <1
+ float endPoint=(phase+i+coverage)/num; //can be >1
+ float endIndex=line.getIndexAtPercent(endPoint>1.0f?endPoint-1.0f:endPoint);
+ ofPolyline segment;
+ segment.addVertex(line.getPointAtIndexInterpolated(startIndex));
+ for (int j=(int)ceil(startIndex);j<(endPoint>1?line.size():(int)ceil(endIndex));j++){
+ segment.addVertex(line[j]);
+ }
+ if (endPoint>1){
+ segments.push_back(segment);
+ segment.clear();
+ for (int j=0;j<(int)ceil(endIndex);j++){
+ segment.addVertex(line[j]);
+ }
+ segment.addVertex(line.getPointAtIndexInterpolated(endIndex));
+ }
+ else {
+ segment.addVertex(line.getPointAtIndexInterpolated(endIndex));
+ }
+ segments.push_back(segment);
+ }
+
+ return segments;
+}
+
+void lineSegmenter::draw(){
+ line.draw();
+ return;
+}
+int lineSegmenter::size(){
+ return line.size();
+}
+
+
+/*
+
+
+
+
+*/ \ No newline at end of file
diff --git a/gui/src/lineSegmenter.h b/gui/src/lineSegmenter.h
new file mode 100644
index 0000000..d858ba2
--- /dev/null
+++ b/gui/src/lineSegmenter.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "ofMain.h"
+
+class lineSegmenter{
+ public:
+ lineSegmenter(ofPolyline &_line){
+ line=_line;
+ if (line.isClosed()){
+ line.addVertex(line[0]);
+ }
+ }
+ const vector <ofPolyline> &getSegments(int num,float coverage, float phase);
+ ofPolyline getPoly(){
+ return line;
+ }
+ void draw();
+ int size();
+ private:
+ ofPolyline line;
+ vector <ofPolyline> segments;
+}; \ No newline at end of file
diff --git a/gui/src/lineTransformer.cpp b/gui/src/lineTransformer.cpp
index bf237d7..a21d020 100644
--- a/gui/src/lineTransformer.cpp
+++ b/gui/src/lineTransformer.cpp
@@ -89,7 +89,7 @@ glm::mat4 lineTransformer::getPerspectiveTransformMatrix(const glm::vec2 src[4],
p[2][8], p[5][8], 0, 1);
}
-ofPolyline lineTransformer::polyLineTransform(const ofPolyline& poly, ofMatrix4x4 xform){
+ofPolyline lineTransformer::polyLineTransform(const ofMatrix4x4 xform, const ofPolyline& poly){
ofPolyline tempPoly;
for (auto& p:poly){
tempPoly.addVertex(ofVec3f(p)*xform);
diff --git a/gui/src/lineTransformer.h b/gui/src/lineTransformer.h
index 8268b81..54424d0 100644
--- a/gui/src/lineTransformer.h
+++ b/gui/src/lineTransformer.h
@@ -10,7 +10,7 @@ class lineTransformer {
void static drawWarpFrame(glm::vec2 warpframe[4]);
void static gaussianElimination(float * input, int n);
glm::mat4 static getPerspectiveTransformMatrix(const glm::vec2 src[4], const glm::vec2 dst[4]);
- ofPolyline static polyLineTransform(const ofPolyline& poly, ofMatrix4x4 xform);
+ ofPolyline static polyLineTransform(const ofMatrix4x4 xform,const ofPolyline& poly);
ofPolyline static makePolygon(int num,float diam);
void static drawPoly(ofPolyline poly,float x,float y);
diff --git a/gui/src/main.cpp b/gui/src/main.cpp
index d8d06d3..bdc0e8a 100644
--- a/gui/src/main.cpp
+++ b/gui/src/main.cpp
@@ -21,7 +21,7 @@ int main(int argc, char *argv[]){
mainWindow->setVerticalSync(false);
settings.width = 600;
- settings.height = 1200;
+ settings.height = 900;
settings.setPosition(ofVec2f(0,0));
settings.resizable = true;
diff --git a/gui/src/ofApp.cpp b/gui/src/ofApp.cpp
index 81e9e0c..689d5ad 100644
--- a/gui/src/ofApp.cpp
+++ b/gui/src/ofApp.cpp
@@ -3,6 +3,8 @@
const ofPoint mainwindowsize=ofPoint(1200,900);
+
+
//--------------------------------------------------------------
void ofApp::setup(){
warpframe[0]=glm::vec2(0,0);
@@ -14,6 +16,8 @@ void ofApp::setup(){
gui.setup();
+ source=SVG_outlines;
+
//==================================================== ofxNDI
senderName[0] = 0; // The sender name used for display
@@ -31,19 +35,26 @@ void ofApp::setup(){
//============================ GUI
- gui.add(NDIthreshold.setup("threshold", 140, 0, 255));
- gui.add(NDIsimplify.setup("simplify", 0.2f, 0.0f, 1.0f));
- gui.add(NDIuseColour.setup("use colour", true));
- gui.add(NDIcolR.setup("red", 140, 0, 255));
- gui.add(NDIcolR.setup("green", 140, 0, 255));
- gui.add(NDIcolG.setup("blue", 140, 0, 255));
+ gui.add(contour_threshold.setup("threshold", 140, 0, 255));
+ gui.add(contour_simplify.setup("simplify", 0.2, 0.0, 1.0));
+ gui.add(contour_useColour.setup("use colour", true));
+ gui.add(laser_R.setup("red", 140, 0, 255));
+ gui.add(laser_G.setup("green", 140, 0, 255));
+ gui.add(laser_B.setup("blue", 140, 0, 255));
+ gui.add(laser_intensity.setup("intensity", 30, 0, 255));
+ gui.add(laser_points.setup("points", 20000, 0, 40000));
+ gui.add(shapes_randomise.setup("randomise shapes", true));
+ gui.add(shapes_amount.setup("shapes amount", 0.2, 0.0, 0.8));
+ gui.add(shapes_duration.setup("shape duration", 5, 0, 25));
+ framecounter=0;
}
//--------------------------------------------------------------
void ofApp::updateOutput(ofEventArgs & args){
-
+ laser.set_pts(laser_points);
+ laser.set_intensity(laser_intensity);
}
@@ -139,13 +150,17 @@ void ofApp::update(){
}
}
+
+ if (movie.isLoaded()){
+ movie.update();
+ }
}
const ofPoint previewframesize=ofPoint(320,240);
-//--------------------------------------------------------------
-void ofApp::draw(){
+//-------------------------------------------------------------- GUI
+void ofApp::draw(){
ofBackground(0);
ofSetColor(255);
@@ -154,10 +169,10 @@ void ofApp::draw(){
gui.draw();
//================================== NDI
-
+/*
glPushMatrix();
- glTranslatef(256,0,0);
+ glTranslatef(230,0,0);
ofDrawRectangle(20,20,previewframesize.x+4,previewframesize.y+4);
@@ -202,6 +217,46 @@ void ofApp::draw(){
glPopMatrix();
+ //================================== NDI
+
+ glPushMatrix();
+
+ glTranslatef(230,300,0);
+*/
+ //================================== video
+
+ glPushMatrix();
+
+ glTranslatef(230,0,0);
+
+ ofDrawRectangle(20,20,previewframesize.x+4,previewframesize.y+4);
+
+ if (movie.isLoaded()){
+ movie.draw(22, 22, previewframesize.x, previewframesize.y);
+ }
+
+ glPopMatrix();
+
+ //================================== SVG
+
+ glPushMatrix();
+
+ float scale=previewframesize.x/mainwindowsize.x;
+
+ glTranslatef(230,300,0);
+
+ ofDrawRectangle(20,20,previewframesize.x+4,previewframesize.y+4);
+
+ glTranslatef(22,22,0);
+
+ glScalef(scale,scale,scale);
+
+ for (auto shape=segmenters.begin();shape!=segmenters.end();shape++){
+ shape->getPoly().draw();
+ }
+
+ glPopMatrix();
+
}
void ofApp::drawOutput(ofEventArgs & args){
@@ -210,35 +265,124 @@ void ofApp::drawOutput(ofEventArgs & args){
ofSetColor(255,255,255);
- ofMatrix4x4 m = ofMatrix4x4::newIdentityMatrix();
- m.rotateRad(ofGetElapsedTimef(),0,0,1);
- m.translate(ofGetWidth()/2,ofGetHeight()/2,0);
+ vector <colourPolyline> laserOutput;
+
+ switch (source){
+ case TEST:{
+ ofMatrix4x4 m = ofMatrix4x4::newIdentityMatrix();
+ m.rotateRad(ofGetElapsedTimef(),0,0,1);
+ m.translate(ofGetWidth()/2,ofGetHeight()/2,0);
+
+ glm::vec2 src[]={
+ glm::vec2(0,0),
+ glm::vec2(ofGetWidth(),0),
+ glm::vec2(ofGetWidth(),ofGetHeight()),
+ glm::vec2(0,ofGetHeight())
+ };
- glm::vec2 src[]={
- glm::vec2(0,0),
- glm::vec2(ofGetWidth(),0),
- glm::vec2(ofGetWidth(),ofGetHeight()),
- glm::vec2(0,ofGetHeight())
- };
+ ofMatrix4x4 warp =lineTransformer::getPerspectiveTransformMatrix(src,warpframe);
- ofMatrix4x4 warp =lineTransformer::getPerspectiveTransformMatrix(src,warpframe);
+ //drawPoly(polyLineTransform(makePolygon(4,200),m),200,200);
+ //drawPoly(polyLineTransform(makePolygon(5,200),m),-200,200);
+ //drawPoly(polyLineTransform(makePolygon(6,200),m),-200,-200);
+
+ ofPolyline poly=lineTransformer::polyLineTransform(warp,
+ lineTransformer::polyLineTransform(m,
+ lineTransformer::makePolygon(6,200)
+ )
+ );
+ laserOutput.push_back(colourPolyline(poly,ofColor(laser_R,laser_G,laser_B)));
+
+ }
+ case NDI:{
+ ofPoint scale=ofPoint(mainwindowsize.x/ndiImage.getWidth(),mainwindowsize.x/ndiImage.getHeight());
+
+ //does not work no matter what the fuck you do
+
+ //grayImage.setFromPixels(pixels.getData(),ndiImage.getWidth(),ndiImage.getHeight());
+
+ //grayImage.draw(0,0,mainwindowsize.x,mainwindowsize.y);
+
+ grayImage = colorImg;
+
+ grayImage.threshold(contour_threshold);
+
+ //virtual int findContours( ofxCvGrayscaleImage& input,
+ // int minArea, int maxArea,
+ // int nConsidered, bool bFindHoles,
+ // bool bUseApproximation = true);
+ contourFinder.findContours(grayImage, 20, (340*240)/3, 10, true);
+
+ for (int i = 0; i < contourFinder.nBlobs; i++){
+ colourPolyline shape;
+ for (auto& point:contourFinder.blobs[i].pts){
+ ofVec3f p=point*scale;
+ ofColor c=colorImg.getPixels().getColor(point.x,point.y);
+ shape.addVertex(p,contour_useColour?c:ofColor(laser_R,laser_G,laser_B));
+ }
+ shape.simplify(contour_simplify);
+ laserOutput.push_back(shape);
+ }
+ break;
+
+ }
+ case Player:{
+ if (movie.isLoaded()){
+ ofPoint scale=ofPoint(mainwindowsize.x/movie.getWidth(),mainwindowsize.y/movie.getHeight());
+ colorImg.setFromPixels(movie.getPixels());
+ grayImage = colorImg;
+ grayImage.threshold(contour_threshold);
+ contourFinder.findContours(grayImage, 20, (340*240)/3, 10, true);
+ for (int i = 0; i < contourFinder.nBlobs; i++){
+ colourPolyline shape;
+ for (auto& point:contourFinder.blobs[i].pts){
+ ofVec3f p=point*scale;
+ ofColor c=colorImg.getPixels().getColor(point.x,point.y);
+ shape.addVertex(p,contour_useColour?c:ofColor(laser_R,laser_G,laser_B));
+ }
+ shape.simplify(contour_simplify);
+ laserOutput.push_back(shape);
+ }
+ }
+ break;
+ }
+ case SVG_outlines:{
+ if (shapes_randomise){
+ if (framecounter==0){
+ select_random_shapes();
+ framecounter=shapes_duration;
+ }
+ for (auto s:shape_selection){
+ laserOutput.push_back(colourPolyline(segmenters[s].getPoly(),ofColor(laser_R,laser_G,laser_B)));
+ }
+ framecounter--;
+ }
+ else {
+ for (auto shape=segmenters.begin();shape!=segmenters.end();shape++){
+ laserOutput.push_back(colourPolyline(shape->getPoly(),ofColor(laser_R,laser_G,laser_B)));
+ }
+ }
+ break;
+ }
+ }
- //drawPoly(polyLineTransform(makePolygon(4,200),m),200,200);
- //drawPoly(polyLineTransform(makePolygon(5,200),m),-200,200);
- //drawPoly(polyLineTransform(makePolygon(6,200),m),-200,-200);
+ int num = laser.draw(laserOutput);
- lineTransformer::drawPoly(
- lineTransformer::polyLineTransform(
- lineTransformer::polyLineTransform(
- lineTransformer::makePolygon(6,200)
- ,m)
- ,warp)
- ,0,0);
+ for (auto& shape:laserOutput){
+ shape.draw();
+ }
- if (bDrawFrame){
+ if (bDrawFrame){
lineTransformer::drawWarpFrame(warpframe);
}
+ if (num>0){
+ ofSetWindowTitle(ofToString(ofGetFrameRate(), 2)+" fps laser points: "+ofToString(num));
+ }
+ else {
+ ofSetWindowTitle(ofToString(ofGetFrameRate(), 2)+" fps laser error ");
+ }
+
}
//--------------------------------------------------------------
@@ -251,11 +395,28 @@ void ofApp::exit() {
//--------------------------------------------------------------
void ofApp::outputKeyPressed(ofKeyEventArgs &args){
+ keyPressed(args);
+
+
+}
+
+void ofApp::keyPressed(ofKeyEventArgs &args){
if (args.key==OF_KEY_COMMAND){
commandPressed=true;
}
switch(args.key){
+ case 'q':{
+ source--;
+ if (source<0){
+ source=Source_end-1;
+ }
+ break;
+ }
+ case 'p':{
+ source=(source+1)%Source_end;
+ break;
+ }
case 'w':{
bDrawFrame=!bDrawFrame;
break;
@@ -264,12 +425,6 @@ void ofApp::outputKeyPressed(ofKeyEventArgs &args){
commandPressed=true;
}
}
-
-
-}
-
-void ofApp::keyPressed(ofKeyEventArgs &args){
-
}
//--------------------------------------------------------------
@@ -334,15 +489,76 @@ void ofApp::windowResized(int w, int h){
}
+void ofApp::select_random_shapes(){
+ shape_selection.clear();
+ while (shape_selection.size()<(segmenters.size()*shapes_amount)){
+ int selection=rand()%segmenters.size();
+ if (shape_selection.find(selection)==shape_selection.end()){
+ shape_selection.insert(selection);
+ }
+ }
+ std::stringstream strm;
+ for (auto& s:shape_selection){
+ strm << s <<" ";
+ }
+ //cout << "randomly selected (" << strm.str() <<") \n";
+}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){
+
+ if (dragInfo.position.x>250&&dragInfo.position.x<570&&dragInfo.position.y>20&&dragInfo.position.y<266){
+ std::string filename= *dragInfo.files.begin();
+ if (movie.load(filename)){
+ cout << "loaded "<< filename<<std::endl;
+ movie.setLoopState(OF_LOOP_NORMAL);
+ movie.play();
+ }
+ else {
+ cout << "failed to load"<<std::endl;
+ }
+ }
+
+ if (dragInfo.position.x>250&&dragInfo.position.x<570&&dragInfo.position.y>320&&dragInfo.position.y<566){
+ std::string filename= *dragInfo.files.begin();
+ svg.load(filename);
+ vector <ofPath> imagepaths= svg.getPaths();
+
+ std::stringstream strm;
+
+ if (imagepaths.size()){
+ segmenters.clear();
+ for (auto& path:imagepaths){
+ path.setPolyWindingMode(OF_POLY_WINDING_ODD);
+
+ vector <ofPolyline> outlines= path.getOutline();
+ for (auto& outline:outlines){
+ strm << outline.size() << "->";
+ outline.simplify(contour_simplify);
+ strm << outline.size() << " ";
+ segmenters.push_back(lineSegmenter(outline));
+ }
+ strm << " , ";
+ }
+
+ cout << "SVG: found " << imagepaths.size() << " paths with " << segmenters.size() << " shapes [ " << strm.str() << " ]" <<std::endl;
+ select_random_shapes();
+ }
+
+ }
+
+}
+
+ //printf("%s at %i %i \n",dragInfo.files.begin(),dragInfo.position.x,dragInfo.position.y);
//std::string filenames;
-
+ //cout << dragInfo.files.begin()->c_str()<<","<<dragInfo.position.x<<","<<dragInfo.position.y<<std::endl;
+
//for (auto f = dragInfo.files.begin(); f != dragInfo.files.end(); f++){
- // if (f!=dragInfo.files.begin()){
- // filenames=filenames+", ";
- // }
+ // cout << f->c_str()<<","<<dragInfo.position.x<<","<<dragInfo.position.y<<std::endl;
+ //if (f!=dragInfo.files.begin()){
+ // filenames=filenames+", ";
+ //}
+ //}
// filenames=filenames+*f;
// if (dragInfo.position.y<200){
@@ -353,4 +569,3 @@ void ofApp::dragEvent(ofDragInfo dragInfo){
//}
-}
diff --git a/gui/src/ofApp.h b/gui/src/ofApp.h
index 3f5acc1..ae0ef60 100644
--- a/gui/src/ofApp.h
+++ b/gui/src/ofApp.h
@@ -4,6 +4,19 @@
#include "lineTransformer.h"
#include "ofxNDI.h"
#include "ofxGui.h"
+#include "ofxHelios.h"
+#include "ofxOpenCv.h"
+#include "ofxSVG.h"
+#include "lineSegmenter.h"
+
+enum Source{
+ TEST,
+ NDI,
+ Player,
+ SVG_outlines,
+ SVG_segmenters,
+ Source_end
+};
class ofApp: public ofBaseApp {
@@ -32,6 +45,8 @@ class ofApp: public ofBaseApp {
void outputMouseReleased(ofMouseEventArgs & args);
void outputWindowResized(ofResizeEventArgs &resizeargs);
+ void select_random_shapes();
+
bool commandPressed;
glm::vec2 warpframe[4];
@@ -40,6 +55,16 @@ class ofApp: public ofBaseApp {
ofxPanel gui;
+ ofxHelios laser;
+
+ int source;
+
+ //======================================== //thresholding
+
+ ofxCvColorImage colorImg;
+ ofxCvGrayscaleImage grayImage;
+ ofxCvContourFinder contourFinder;
+
//======================================== //ofxNDI
ofxNDIreceiver ndiReceiver;
@@ -53,13 +78,29 @@ class ofApp: public ofBaseApp {
// For received frame fps calculations
double startTime, lastTime, frameTime, frameRate, fps;
- //====== gui
+ //====== video input gui
+
+ ofxIntSlider contour_threshold;
+ ofxFloatSlider contour_simplify;
+ ofxToggle contour_useColour;
+ ofxIntSlider laser_R;
+ ofxIntSlider laser_G;
+ ofxIntSlider laser_B;
+ ofxIntSlider laser_intensity;
+ ofxIntSlider laser_points;
+ ofxToggle shapes_randomise;
+ ofxFloatSlider shapes_amount;
+ ofxIntSlider shapes_duration;
+
+ //======================================= //video player
+
+ ofVideoPlayer movie;
+
+ //======================================= //SVG player
- ofxIntSlider NDIthreshold;
- ofxIntSlider NDIsimplify;
- ofxToggle NDIuseColour;
- ofxIntSlider NDIcolR;
- ofxIntSlider NDIcolG;
- ofxIntSlider NDIcolB;
+ ofxSVG svg;
+ vector <lineSegmenter> segmenters;
+ set <int> shape_selection;
+ int framecounter;
};