diff options
| author | Tim Redfern <tim@eclectronics.org> | 2012-06-14 02:04:16 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2012-06-14 02:04:16 +0100 |
| commit | 58f154e844aed7ba06df3ac570521930de66b744 (patch) | |
| tree | 198901f4cba5ee5621d8fe27d4704825c54dd98f /gaunt01 | |
| parent | eecd5a7eb92f24a1e9d3a2e6853363f23ccfccb2 (diff) | |
mostly good
Diffstat (limited to 'gaunt01')
| -rw-r--r-- | gaunt01/bin/data/settings.xml | 2 | ||||
| -rw-r--r-- | gaunt01/src/bird.cpp | 13 | ||||
| -rw-r--r-- | gaunt01/src/bird.h | 2 | ||||
| -rw-r--r-- | gaunt01/src/main.cpp | 2 | ||||
| -rw-r--r-- | gaunt01/src/testApp.cpp | 271 | ||||
| -rw-r--r-- | gaunt01/src/testApp.h | 38 |
6 files changed, 297 insertions, 31 deletions
diff --git a/gaunt01/bin/data/settings.xml b/gaunt01/bin/data/settings.xml index f482957..db07922 100644 --- a/gaunt01/bin/data/settings.xml +++ b/gaunt01/bin/data/settings.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<gauntlet cam_angle="-55" threshold="30" /> +<gauntlet cam_angle="-55" threshold="30" keyChannel="6" /> <bounds> <vertex x="362.884" y="864.936"></vertex> <vertex x="661.116" y="864.936"></vertex> diff --git a/gaunt01/src/bird.cpp b/gaunt01/src/bird.cpp index da246d1..2c4d5f2 100644 --- a/gaunt01/src/bird.cpp +++ b/gaunt01/src/bird.cpp @@ -178,7 +178,7 @@ void bird::update(map<int,player>& players, float angle){ if (position.z<-ofGetHeight()/40) { if (diveRate<2.0f) { //increase dive rate - diveRate+=0.2f; + diveRate+=0.1f; } } else { @@ -212,6 +212,7 @@ void bird::update(map<int,player>& players, float angle){ //do the documentation //go back to the bird - watch out for dead players (from trap doors) - bird is going out of play - just retrieve it for now? //flap faster while climbing + swoop + //bird noises heading=heading+(turnRate*timeSeg); while (heading>180) heading=heading-360; @@ -255,10 +256,12 @@ void bird::drawDebug(){ ofSphere(edgepoint,2.0f); */ - ofSetHexColor(0xff00ff); - char numStr[64]; - sprintf(numStr, "dive: %4.2f\nheight: %4.2f", diveRate,position.z); - ofDrawBitmapString(numStr,10,10); + if (DEBUG) { + ofSetHexColor(0xff00ff); + char numStr[64]; + sprintf(numStr, "dive: %4.2f\nheight: %4.2f", diveRate,position.z); + ofDrawBitmapString(numStr,10,10); + } } diff --git a/gaunt01/src/bird.h b/gaunt01/src/bird.h index f413911..11585c2 100644 --- a/gaunt01/src/bird.h +++ b/gaunt01/src/bird.h @@ -48,6 +48,8 @@ #include "ofxRay.h" +#define DEBUG 0 + class bird { public: diff --git a/gaunt01/src/main.cpp b/gaunt01/src/main.cpp index d8ec5c8..1f3ac12 100644 --- a/gaunt01/src/main.cpp +++ b/gaunt01/src/main.cpp @@ -6,7 +6,7 @@ int main( ){ ofAppGlutWindow window; - ofSetupOpenGL(&window, 1024,768, OF_WINDOW ); // <-------- setup the GL context + ofSetupOpenGL(&window, 1024,768, OF_FULLSCREEN ); // <-------- setup the GL context printf("%ix%i on screen %ix%i\n",ofGetWidth(),ofGetHeight(),ofGetScreenWidth(),ofGetScreenHeight()); // this kicks off the running of my app // can be OF_WINDOW or OF_FULLSCREEN diff --git a/gaunt01/src/testApp.cpp b/gaunt01/src/testApp.cpp index 749f6d3..bb9bb10 100644 --- a/gaunt01/src/testApp.cpp +++ b/gaunt01/src/testApp.cpp @@ -30,8 +30,6 @@ void testApp::setup(){ loadSettings("settings.xml"); - vidPlayer.loadMovie("camoutput.mov"); //footage/ camera needs to be the same res as opencv planes and output - vidPlayer.setLoopState(OF_LOOP_NORMAL); vidGrabber.setVerbose(true); if (vidGrabber.initGrabber(640,480)) { hasCamera=true; @@ -41,19 +39,45 @@ void testApp::setup(){ { hasCamera=false; useCamera=false; + vidPlayer.loadMovie("camoutput.mov"); //footage/ camera needs to be the same res as opencv planes and output + vidPlayer.setLoopState(OF_LOOP_NORMAL); vidPlayer.play(); } + /* accumImg.allocate(640,480); bgImg.allocate(640,480); bgImg.setUseTexture(true); - colorImg.allocate(640,480); - colorImg.setUseTexture(true);
+
grayImage.allocate(640,480); grayBg.allocate(640,480); + */ + + colorImg.allocate(640,480); + colorImg.setUseTexture(true); + currentFrame.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + background.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + background.setUseTexture(true); + + grayFrame.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + grayBg.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + grayDiff.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + + mogoutput.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + + learningRate = 0.01f; + bFirstFrame=true; + + diffchannel=chan_V; + hsvback = cvCreateImage(cvGetSize(currentFrame.getCvImage()), currentFrame.getCvImage()->depth, currentFrame.getCvImage()->nChannels); + //backchan = cvCreateImage(cvGetSize(currentFrame.getCvImage()), 8, 1); + + removeShadows=false; + shadowThreshold=10; + //////////////////////////// blobsManager.normalizePercentage = 0.7; blobsManager.giveLowestPossibleIDs = false; @@ -437,6 +461,8 @@ void testApp::update(){ } colorImg.updateTexture(); + + /* grayImage = colorImg; @@ -453,15 +479,6 @@ void testApp::update(){ bgImg=accumImg; bgImg.updateTexture(); - //test the scaling - - /* - grayImage.resize(windowWidth,windowHeight); - if (bLearnBakground == true){ - grayBg = grayImage; // the = sign copys the pixels from grayImage into grayBg (operator overloading) - bLearnBakground = false; - } - */ grayDiff.clear(); grayDiff.allocate(640,480); @@ -477,6 +494,178 @@ void testApp::update(){ //hard coded size threshold of 100 pix contourFinder.findContours(grayDiff, 200, (640*480)/3, 20, false); // don't find holes + + */ + + cv::Mat img = colorImg.getCvImage(); + + //if (frameno%1==0) { //I THINK THIS APPROACH IS OK to attempt to lower cpu hit from accumulating? + + //cv::Rect roi(0, 0, 32, 32); //doesn't seem that easy to apply the ROI weighted and you still have to convert a whole image each frame? + + //cv::Mat imgroi = img(roi); + + if (bFirstFrame) { + img.convertTo(accumulator, CV_32FC3); + bFirstFrame=false; + } + + cv::Mat im3; + img.convertTo(im3, CV_32FC3); + + + + //accumulator; + accumulateWeighted(im3, accumulator, max(1.0f/(ofGetElapsedTimef()*30.0f),learningRate)); + accumulator.convertTo(outmat,CV_8UC3); + + IplImage* tmp = new IplImage(outmat); + background=tmp; + background.updateTexture(); + + //printf("tmp: %ix%i channels: %i depth:%i\n",tmp->width,tmp->height,tmp->nChannels,tmp->depth); + + + //get correct channel into backchan + + vector<cv::Mat> chans; + + //to remove shadows, need hsv of foreground and background + if (diffchannel>chan_B||removeShadows) cvtColor(outmat, hsvback, CV_BGR2HSV); + switch (diffchannel) { + case chan_R: + split(outmat,chans); + chans[0].copyTo(backchan); + break; + case chan_G: + split(outmat,chans); + chans[1].copyTo(backchan); + break; + case chan_B: + split(outmat,chans); + chans[2].copyTo(backchan); + break; + case chan_H: + split(hsvback,chans); + chans[0].copyTo(backchan); + break; + case chan_S: + split(hsvback,chans); + chans[1].copyTo(backchan); + break; + case chan_V: + split(hsvback,chans); + chans[2].copyTo(backchan); + break; + } + + + tmp = new IplImage(backchan); + grayBg = tmp; + + //} + //first, optionally remove shadows from FG + //possibly use 1/4 screen res? + + //to remove shadows, need hsv of foreground and background + if (diffchannel>chan_B||removeShadows) cvtColor(img, hsvfront, CV_BGR2HSV); + + cv::Mat outimg; + + if (removeShadows) { + vector<cv::Mat> slicesFront, slicesBack; + cv::Mat valFront, valBack, satFront, satBack; + + // split image to H,S and V images + split(hsvfront, slicesFront); + split(hsvback, slicesBack); + + slicesFront[2].copyTo(valFront); // get the value channel + slicesFront[1].copyTo(satFront); // get the sat channel + + slicesBack[2].copyTo(valBack); // get the value channel + slicesBack[1].copyTo(satBack); // get the sat channel + + int x,y; + for(x=0; x<currentFrame.getWidth(); ++x) { + for(y=0; y<currentFrame.getHeight(); ++y) { + bool sat = ((satFront.at<cv::Vec3b>(y,x)[0] > satBack.at<cv::Vec3b>(y,x)[0]-shadowThreshold) && + (satFront.at<cv::Vec3b>(y,x)[0] < satBack.at<cv::Vec3b>(y,x)[0]+shadowThreshold)); + + if(sat && (valFront.at<cv::Vec3b>(y,x)[0] < valBack.at<cv::Vec3b>(y,x)[0])) { + hsvfront.at<cv::Vec3b>(y,x)[0]= hsvback.at<cv::Vec3b>(y,x)[0]; + hsvfront.at<cv::Vec3b>(y,x)[1]= hsvback.at<cv::Vec3b>(y,x)[1]; + hsvfront.at<cv::Vec3b>(y,x)[2]= hsvback.at<cv::Vec3b>(y,x)[2]; + } + + } + } + + //convert back into RGB if necessary + + if (diffchannel<chan_H) cvtColor(hsvfront, outimg, CV_HSV2BGR); + else outimg=hsvfront; + + }else { + outimg=img; + } + + + //select correct channel for comparison and put into grayFrame + + //vector<cv::Mat> chans; + split(outimg,chans); + + switch (diffchannel) { + case chan_R: + chans[0].copyTo(frontchan); + break; + case chan_G: + chans[1].copyTo(frontchan); + break; + case chan_B: + chans[2].copyTo(frontchan); + break; + case chan_H: + chans[0].copyTo(frontchan); + break; + case chan_S: + chans[1].copyTo(frontchan); + break; + case chan_V: + chans[2].copyTo(frontchan); + break; + } + + //IplImage* tmp = new IplImage(outmat); + tmp = new IplImage(frontchan); + grayFrame = tmp; + + grayDiff.clear(); + grayDiff.allocate(640,480); + + // take the abs value of the difference between background and incoming and then threshold: + grayDiff.absDiff(grayBg, grayFrame); + grayDiff.threshold(threshold); + //grayFrame.adaptiveThreshold( threshold,10,false,true); //int blockSize, int offset=0,bool invert=false, bool gauss=false); + //grayDiff.erode_3x3(); + //grayDiff.resize(windowWidth,windowHeight); + +/* + //MOG + mog(img, outmat, mogf); + + // Complement the image + //cv::threshold(outmat, output, threshold, 255, cv::THRESH_BINARY_INV); + IplImage* tmp1 = new IplImage(outmat); + //printf("tmp: %ix%i channels: %i depth:%i\n",tmp->width,tmp->height,tmp->nChannels,tmp->depth); + //printf("grayDiff: %ix%i channels: %i depth:%i\n",grayDiff.getCvImage()->width,grayDiff.getCvImage()->height,grayDiff.getCvImage()->nChannels,grayDiff.getCvImage()->depth); + grayDiff=tmp1; //copy to ofx +*/ + + grayDiff.resize(windowWidth,windowHeight); //wasteful?? + + contourFinder.findContours(grayDiff, 500, (640*480)/3, 20, false); // find holes blobsManager.update(contourFinder.blobs); //check players against blob ids - bland do ray casting, update players @@ -557,9 +746,11 @@ void testApp::draw(){ //should be in front with holes being recreated for activated trapdoors ofSetHexColor(0xffffff); - bindTexture(bgImg); + if (mode==CALIBRATE) bindTexture(colorImg); + else bindTexture(background); ground.draw(); - unbindTexture(bgImg); + if (mode==CALIBRATE) unbindTexture(colorImg); + else unbindTexture(background); ofPushMatrix(); ofRotate(cam_angle,1,0,0); @@ -579,7 +770,7 @@ void testApp::draw(){ glDisable(GL_BLEND); ofPopMatrix(); - + glDisable(GL_DEPTH_TEST); ofSetHexColor(0xffffff); bindTexture(colorImg); //colorImg.getTextureReference().bind(); @@ -746,12 +937,15 @@ void testApp::draw(){ char numStr[16]; sprintf(numStr, "%i", blobsManager.blobs[i].id); ofDrawBitmapString(numStr, blob.boundingRect.x, blob.boundingRect.y); + + /* ofPushMatrix(); ofRotate(cam_angle,1,0,0); ofTranslate(players[blobsManager.blobs.at(i).id].getWorldPosition()); ofBox(0,-10,0,20); //TODO get this into plane axis ofPopMatrix(); + */ // } @@ -773,13 +967,15 @@ void testApp::draw(){ if (drawStats||mode==CALIBRATE) { ofSetHexColor(0xffffff); char reportStr[1024]; - sprintf(reportStr, "threshold %i\nnum blobs found %i, fps: %f", threshold, contourFinder.nBlobs, ofGetFrameRate()); - ofDrawBitmapString(reportStr, 10, windowHeight-40); + sprintf(reportStr, "threshold %i",threshold); //\nnum blobs found %i, fps: %f", threshold, contourFinder.nBlobs, ofGetFrameRate()); + ofDrawBitmapString(reportStr, 10, windowHeight-30); + /* char numStr[16]; for(int i=0;i<blobsManager.blobs.size();i++){ sprintf(numStr, "%i", blobsManager.blobs[i].id); ofDrawBitmapString(numStr, 10+(i*30), windowHeight-55); } + */ } cam.end(); } @@ -788,9 +984,6 @@ void testApp::draw(){ void testApp::keyPressed(int key){ switch (key){ - case ' ': - bLearnBakground = true; - break; case '+': threshold ++; if (threshold > 255) threshold = 255; @@ -819,7 +1012,34 @@ void testApp::keyPressed(int key){ case '0': mode=CALIBRATE; break; - case '1': + + case '1': + diffchannel = chan_R; + break; + case '2': + diffchannel = chan_G; + break; + case '3': + diffchannel = chan_B; + break; + case '4': + diffchannel = chan_H; + break; + case '5': + diffchannel = chan_S; + break; + case '6': + diffchannel = chan_V; + break; + + /* + case 's': + removeShadows=!removeShadows; + printf(removeShadows?"removing shadows\n":"not removing shadows\n"); + break; + + + case '1': if (Bird.currentseq!="hover") { //mesh.sequences["trans_flaphover"].stopAt(0.3); //mesh.sequences["trans_flaphover"].start(); @@ -859,6 +1079,7 @@ void testApp::keyPressed(int key){ Bird.currentseq="attack"; } break; + */ /* case 'y': light.setPosition(light.getX(),light.getY()-100,light.getZ()); @@ -891,11 +1112,13 @@ void testApp::keyPressed(int key){ drawingborder=true; } else drawingborder=false; - break; + /* case '>': gameState=(gameState+1)%4; gameStart=ofGetElapsedTimef(); break; + + */ } } @@ -950,6 +1173,7 @@ void testApp::loadSettings(string filename){ }else{ cam_angle=ofToInt(XML.getAttribute("gauntlet","cam_angle","none",0)); threshold=ofToInt(XML.getAttribute("gauntlet","threshold","none",0)); + diffchannel=ofToInt(XML.getAttribute("gauntlet","keyChannel","none",0)); if(XML.pushTag("bounds")) { for (int i=0;i<XML.getNumTags("vertex");i++){ border.push_back(ofVec2f(ofToFloat(XML.getAttribute("vertex","x","0",i)),ofToFloat(XML.getAttribute("vertex","y","0",i)))); @@ -963,6 +1187,7 @@ void testApp::loadSettings(string filename){ void testApp::saveSettings(string filename){ XML.setAttribute("gauntlet","cam_angle",ofToString(cam_angle),0); XML.setAttribute("gauntlet","threshold",ofToString(threshold),0); + XML.setAttribute("gauntlet","keyChannel",ofToString(diffchannel),0); if (XML.tagExists("bounds")) XML.removeTag("bounds"); XML.addTag("bounds"); if(XML.pushTag("bounds")) { diff --git a/gaunt01/src/testApp.h b/gaunt01/src/testApp.h index ca10681..529acec 100644 --- a/gaunt01/src/testApp.h +++ b/gaunt01/src/testApp.h @@ -28,6 +28,17 @@ #define PLAYING 3 #define GOTCHA 4 +#define CAM_WIDTH_FG 640 +#define CAM_HEIGHT_FG 480 + +#define chan_R 1 +#define chan_G 2 +#define chan_B 3 +#define chan_H 4 +#define chan_S 5 +#define chan_V 6 + +#define DEBUG 0 class testApp : public ofBaseApp{ @@ -65,13 +76,38 @@ class testApp : public ofBaseApp{ ofVideoGrabber vidGrabber; ofVideoPlayer vidPlayer; - ofxCvColorImage colorImg;
+ ofxCvColorImage colorImg; + + int diffchannel; + + cv::Mat accumulator,outmat,hsvback,hsvfront,backchan,frontchan,output; // background accumulation + + ofxCvColorImage currentFrame; + ofxCvColorImage background; + + ofxCvColorImage mogoutput; + + ofxCvGrayscaleImage grayFrame; + ofxCvGrayscaleImage grayBg; + ofxCvGrayscaleImage grayDiff; + + float learningRate; + bool bFirstFrame; + + //cv::BackgroundSubtractorMOG mog; + + float mogf; + + bool removeShadows; + int shadowThreshold; + /*
ofxCvFloatImage accumImg; ofxCvGrayscaleImage bgImg; ofxCvGrayscaleImage grayImage; ofxCvGrayscaleImage grayBg; ofxCvGrayscaleImage grayDiff; + */ ofxCvContourFinder contourFinder; |
