From e05bc2828bc213f1e78256f976284bad80722e1a Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Wed, 13 Jun 2012 14:52:22 +0100 Subject: avoiding edges version --- cvtest/src/testApp.cpp | 165 +++++++++++++++++++++++++++++++++++++------------ cvtest/src/testApp.h | 5 +- 2 files changed, 129 insertions(+), 41 deletions(-) (limited to 'cvtest/src') diff --git a/cvtest/src/testApp.cpp b/cvtest/src/testApp.cpp index cf5061d..cfde019 100644 --- a/cvtest/src/testApp.cpp +++ b/cvtest/src/testApp.cpp @@ -25,7 +25,7 @@ void testApp::setup(){ } - vidPlayer.loadMovie("cam-grass-01.mov"); //camoutput3.mov"); // //footage/ camera needs to be the same res as opencv planes and output + vidPlayer.loadMovie("camoutput3.mov"); //cam-grass-01.mov"); // //footage/ camera needs to be the same res as opencv planes and output vidPlayer.setLoopState(OF_LOOP_NORMAL); vidPlayer.play(); @@ -39,7 +39,7 @@ void testApp::setup(){ mogoutput.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); - learningRate = 0.1f; + learningRate = 0.01f; bFirstFrame=true; threshold=10.0; @@ -80,7 +80,10 @@ void testApp::setup(){ diffchannel=chan_V; hsvback = cvCreateImage(cvGetSize(currentFrame.getCvImage()), currentFrame.getCvImage()->depth, currentFrame.getCvImage()->nChannels); - //outchan = cvCreateImage(cvGetSize(currentFrame.getCvImage()), 8, 1); + //backchan = cvCreateImage(cvGetSize(currentFrame.getCvImage()), 8, 1); + + removeShadows=false; + shadowThreshold=10; } @@ -98,12 +101,12 @@ void testApp::update(){ currentFrame.setFromPixels(vidPlayer.getPixels(), CAM_WIDTH_FG, CAM_HEIGHT_FG); + cv::Mat img = currentFrame.getCvImage(); - - if (frameno%10==0) { //I THINK THIS APPROACH IS OK + if (frameno%1==0) { //I THINK THIS APPROACH IS OK //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 img = currentFrame.getCvImage(); + //cv::Mat imgroi = img(roi); if (bFirstFrame) { @@ -126,70 +129,140 @@ void testApp::update(){ //printf("tmp: %ix%i channels: %i depth:%i\n",tmp->width,tmp->height,tmp->nChannels,tmp->depth); - //get correct channel into outchan + //get correct channel into backchan vector chans; - if (diffchannel>chan_B) cvtColor(outmat, hsvback, CV_BGR2HSV); + //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(outchan); + chans[0].copyTo(backchan); break; case chan_G: split(outmat,chans); - chans[1].copyTo(outchan); + chans[1].copyTo(backchan); break; case chan_B: split(outmat,chans); - chans[2].copyTo(outchan); + chans[2].copyTo(backchan); break; case chan_H: split(hsvback,chans); - chans[0].copyTo(outchan); + chans[0].copyTo(backchan); break; case chan_S: split(hsvback,chans); - chans[1].copyTo(outchan); + chans[1].copyTo(backchan); break; case chan_V: split(hsvback,chans); - chans[2].copyTo(outchan); + chans[2].copyTo(backchan); break; } - tmp = new IplImage(outchan); - //printf("tmp: %ix%i channels: %i depth:%i\n",tmp->width,tmp->height,tmp->nChannels,tmp->depth); - //printf("grayBg: %ix%i channels: %i depth:%i\n",grayBg.getCvImage()->width,grayBg.getCvImage()->height,grayBg.getCvImage()->nChannels,grayBg.getCvImage()->depth); + 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 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 - grayBg = tmp; + slicesBack[2].copyTo(valBack); // get the value channel + slicesBack[1].copyTo(satBack); // get the sat channel - } - grayFrame = currentFrame; + int x,y; + for(x=0; x(y,x)[0] > satBack.at(y,x)[0]-shadowThreshold) && + (satFront.at(y,x)[0] < satBack.at(y,x)[0]+shadowThreshold)); + + if(sat && (valFront.at(y,x)[0] < valBack.at(y,x)[0])) { + hsvfront.at(y,x)[0]= hsvback.at(y,x)[0]; + hsvfront.at(y,x)[1]= hsvback.at(y,x)[1]; + hsvfront.at(y,x)[2]= hsvback.at(y,x)[2]; + } + + } + } + //convert back into RGB if necessary + + if (diffchannel 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; + + // 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 + //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 */ - contourFinder.findContours(grayDiff, 200, (640*480)/3, 20, false); // find holes + contourFinder.findContours(grayDiff, 200, (640*480)/3, 20, false); // find holes @@ -280,11 +353,11 @@ void testApp::draw(){ } - ofSetHexColor(0xffffff); + ofSetHexColor(0xff0000); char reportStr[1024]; - sprintf(reportStr, "fps: %f\nthreshold: %f", ofGetFrameRate(),threshold); + sprintf(reportStr, "fps: %f\nthreshold: %f\nshadow threshold: %i", ofGetFrameRate(),threshold,shadowThreshold); //sprintf(reportStr, "fps: %f\nmog: %f", ofGetFrameRate(),mogf); - ofDrawBitmapString(reportStr, 1100, 440); + ofDrawBitmapString(reportStr, 1100, 420); } @@ -292,7 +365,7 @@ void testApp::draw(){ //-------------------------------------------------------------- void testApp::keyPressed(int key){ switch (key){ - case '+': + case '=': threshold ++; mogf +=.001; if (threshold > 255) threshold = 255; @@ -302,6 +375,14 @@ void testApp::keyPressed(int key){ mogf-=.001; if (threshold < 0) threshold = 0; break; + case '+': + shadowThreshold ++; + if (shadowThreshold > 255) threshold = 255; + break; + case '_': + shadowThreshold --; + if (shadowThreshold < 0) threshold = 0; + break; case '1': diffchannel = chan_R; break; @@ -320,6 +401,10 @@ void testApp::keyPressed(int key){ case '6': diffchannel = chan_V; break; + case 's': + removeShadows=!removeShadows; + printf(removeShadows?"removing shadows\n":"not removing shadows\n"); + break; } } diff --git a/cvtest/src/testApp.h b/cvtest/src/testApp.h index 4207bb9..32d7158 100644 --- a/cvtest/src/testApp.h +++ b/cvtest/src/testApp.h @@ -47,7 +47,7 @@ class testApp : public ofBaseApp{ //try to accumulate background using SHORT datatype ie CV_16UC / 4 (would 4 be faster, 64 bits) - cv::Mat accumulator,outmat,hsvback,outchan,output; // background accumulation + cv::Mat accumulator,outmat,hsvback,hsvfront,backchan,frontchan,output; // background accumulation int frameno; ofxCvColorImage currentFrame; @@ -72,6 +72,9 @@ class testApp : public ofBaseApp{ int diffchannel; + bool removeShadows; + int shadowThreshold; + /* ofxOpenCvUtilsForeground* fg; ofxOpenCvUtilsMeanShift* meanShift; -- cgit v1.2.3