diff options
Diffstat (limited to 'gui/src')
| -rw-r--r-- | gui/src/lineSegmenter.cpp | 71 | ||||
| -rw-r--r-- | gui/src/lineSegmenter.h | 22 | ||||
| -rw-r--r-- | gui/src/lineTransformer.cpp | 2 | ||||
| -rw-r--r-- | gui/src/lineTransformer.h | 2 | ||||
| -rw-r--r-- | gui/src/main.cpp | 2 | ||||
| -rw-r--r-- | gui/src/ofApp.cpp | 301 | ||||
| -rw-r--r-- | gui/src/ofApp.h | 55 |
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; }; |
