diff options
| author | Tim Redfern <tim@eclectronics.org> | 2012-05-14 19:00:08 +0100 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2012-05-14 19:00:08 +0100 |
| commit | dbf9692b03ac2485f771993184222f7170e71cf2 (patch) | |
| tree | 9a17e44304856b5daa9d91172eb40f6e1783b1da /cvtest/src | |
| parent | e333ec0659a74899fbd75c5ed490089d0fd7d244 (diff) | |
working on background segmentation
Diffstat (limited to 'cvtest/src')
| -rwxr-xr-x | cvtest/src/imageComparator.h | 71 | ||||
| -rw-r--r-- | cvtest/src/main.cpp | 16 | ||||
| -rw-r--r-- | cvtest/src/testApp.cpp | 280 | ||||
| -rw-r--r-- | cvtest/src/testApp.h | 88 |
4 files changed, 455 insertions, 0 deletions
diff --git a/cvtest/src/imageComparator.h b/cvtest/src/imageComparator.h new file mode 100755 index 0000000..c1904c6 --- /dev/null +++ b/cvtest/src/imageComparator.h @@ -0,0 +1,71 @@ +/*------------------------------------------------------------------------------------------*\
+ This file contains material supporting chapter 4 of the cookbook:
+ Computer Vision Programming using the OpenCV Library.
+ by Robert Laganiere, Packt Publishing, 2011.
+
+ This program is free software; permission is hereby granted to use, copy, modify,
+ and distribute this source code, or portions thereof, for any purpose, without fee,
+ subject to the restriction that the copyright notice may not be removed
+ or altered from any source or altered source distribution.
+ The software is released on an as-is basis and without any warranties of any kind.
+ In particular, the software is not guaranteed to be fault-tolerant or free from failure.
+ The author disclaims all warranties with regard to this software, any use,
+ and any consequent failure, is purely the responsibility of the user.
+
+ Copyright (C) 2010-2011 Robert Laganiere, www.laganiere.name
+\*------------------------------------------------------------------------------------------*/
+
+#if !defined ICOMPARATOR
+#define ICOMPARATOR
+
+#include <opencv2/opencv.hpp>
+#include "colorhistogram.h"
+
+class ImageComparator {
+
+ private:
+
+ cv::Mat reference;
+ cv::Mat input;
+ cv::MatND refH;
+ cv::MatND inputH;
+
+ ColorHistogram hist;
+ int div;
+
+ public:
+
+ ImageComparator() : div(32) {
+
+ }
+
+ // Color reduction factor
+ // The comparaison will be made on images with
+ // color space reduced by this factor in each dimension
+ void setColorReduction( int factor) {
+
+ div= factor;
+ }
+
+ int getColorReduction() {
+
+ return div;
+ }
+
+ void setReferenceImage(const cv::Mat& image) {
+
+ reference= hist.colorReduce(image,div);
+ refH= hist.getHistogram(reference);
+ }
+
+ double compare(const cv::Mat& image) {
+
+ input= hist.colorReduce(image,div);
+ inputH= hist.getHistogram(input);
+
+ return cv::compareHist(refH,inputH,CV_COMP_CHISQR);
+ }
+};
+
+
+#endif
diff --git a/cvtest/src/main.cpp b/cvtest/src/main.cpp new file mode 100644 index 0000000..42c1e8d --- /dev/null +++ b/cvtest/src/main.cpp @@ -0,0 +1,16 @@ +#include "ofMain.h" +#include "testApp.h" +#include "ofAppGlutWindow.h" + +//======================================================================== +int main( ){ + + ofAppGlutWindow window; + ofSetupOpenGL(&window, 1280,480, OF_WINDOW ); // <-------- 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 + // pass in width and height too: + ofRunApp( new testApp()); + +} diff --git a/cvtest/src/testApp.cpp b/cvtest/src/testApp.cpp new file mode 100644 index 0000000..a05cc49 --- /dev/null +++ b/cvtest/src/testApp.cpp @@ -0,0 +1,280 @@ +#include "testApp.h" + +//-------------------------------------------------------------- +//units ~ 10cm +// +/* +Can use a floating point image or array to accumulate the screen and generate averaged background? + +Is this too much work for every frame? Should it be put in a seperate thread? + +*/ + +void testApp::setup(){ + + printf("setup: %ix%i on screen %ix%i\n",ofGetWidth(),ofGetHeight(),ofGetScreenWidth(),ofGetScreenHeight()); + + int windowMode = ofGetWindowMode(); + if(windowMode == OF_FULLSCREEN){ + windowWidth = ofGetScreenWidth(); + windowHeight = ofGetScreenHeight(); + } + else if(windowMode == OF_WINDOW){ + windowWidth = ofGetWidth(); + windowHeight = ofGetHeight(); + } + + + 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(); + + currentFrame.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + background.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + + 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.001f; + bFirstFrame=true; + + threshold=10.0; + + mogf=0.008; + /* + fg = new ofxOpenCvUtilsForeground(); + + //method(ACCUMULATE_WEIGHTED) + //,learningRate(0.01) + //,threshold(10) + //,blockSize(6) + //,blur(0) + //,backgroundSet(false)); + + + + fg->threshold = 10.0f; //threshold; + fg->learningRate = 0.01f; // learningRate; + fg->blockSize = 5.0f; //blockSize; + fg->blur = 1.0f; //blockSize; + fg->shadowThreshold = 10.0f; //shadowThreshold; + + + + meanShift = new ofxOpenCvUtilsMeanShift(); + + + resultFrame.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + blobFrame.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + trackFrame.allocate(CAM_WIDTH_FG, CAM_HEIGHT_FG); + + selectEnabled = false; + */ + + ofSetFrameRate(30); + +} + + +//-------------------------------------------------------------- +void testApp::update(){ + + bool bNewFrame = false; + + + vidPlayer.idleMovie(); + bNewFrame = vidPlayer.isFrameNew(); + + if (bNewFrame) { + + currentFrame.setFromPixels(vidPlayer.getPixels(), CAM_WIDTH_FG, CAM_HEIGHT_FG); + cv::Mat img = currentFrame.getCvImage(); + + + cv::Mat im3; + img.convertTo(im3, CV_32FC3); + + if (bFirstFrame) { + img.convertTo(accumulator, CV_32FC3); + bFirstFrame=false; + } + + //accumulator; + accumulateWeighted(im3, accumulator, max(1.0f/(ofGetElapsedTimef()*30.0f),learningRate)); + + accumulator.convertTo(outmat,CV_8UC3); + IplImage* tmp = new IplImage(outmat); + //printf("tmp: %ix%i channels: %i depth:%i\n",tmp->width,tmp->height,tmp->nChannels,tmp->depth); + //printf("output: %ix%i channels: %i depth:%i\n",output.getCvImage()->width,output.getCvImage()->height,output.getCvImage()->nChannels,output.getCvImage()->depth); + background=tmp; + + //grayBg = background; + //grayFrame = currentFrame; + + + // take the abs value of the difference between background and incoming and then threshold: + //grayDiff.absDiff(grayBg, grayFrame); + //grayDiff.threshold(threshold); + //grayDiff.adaptiveThreshold( threshold,1,false,true); //int blockSize, int offset=0,bool invert=false, bool gauss=false); + //grayDiff.erode_3x3(); + //grayDiff.resize(windowWidth,windowHeight); + //contourFinder.findContours(grayDiff, 200, (640*480)/3, 20, false); // don't find holes + + //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 + + + + /* + if (!fg->backgroundSet) fg->setBackground(currentFrame.getCvImage()); + + if(isTracking) { + // define ROI + cv::Mat img = currentFrame.getCvImage(); + cv::Mat img2; + + IplImage imgf = fg->update(currentFrame.getCvImage()); + + cvNot(&imgf, &imgf); + resultFrame = &imgf; + + blobFrame = resultFrame; + cv::Mat mask = blobFrame.getCvImage(); + cv::threshold(mask,mask,128,255,cv::THRESH_BINARY_INV); + cv::add(mask,img,img2); + + IplImage* tmp = new IplImage(img2); + trackFrame = tmp; + + meanShift->update(tmp); + + return; + } + + if(bNewFrame && fg->backgroundSet) { + + + if((int)blur%2==0) { + blur++; + } + fg->blur = blur; + + if(useMoG) { + fg->setMethod(MIXTURE_OF_GUASSIAN); + } else { + fg->setMethod(ACCUMULATE_WEIGHTED); + } + + // Update the fg + IplImage img = fg->update(currentFrame.getCvImage()); + cvNot(&img, &img); + resultFrame = &img; + + blobFrame = resultFrame; + } + */ + + } + + + + +} + +//-------------------------------------------------------------- +void testApp::draw(){ + + ofSetHexColor(0xffffff); + + background.draw(0, 0); + grayDiff.draw(640, 0); + //mogoutput.draw(640, 0); + + /* + + if(fg->backgroundSet) { + + resultFrame.draw(0, 0); + //if(isTracking) { + // trackFrame.draw(320,240); + //} else { + blobFrame.draw(640,0); + //} + } + */ + ofSetHexColor(0xffffff); + char reportStr[1024]; + //sprintf(reportStr, "fps: %f\nthreshold: %f", ofGetFrameRate(),threshold); + sprintf(reportStr, "fps: %f\nmog: %f", ofGetFrameRate(),mogf); + ofDrawBitmapString(reportStr, 1100, 440); + + +} + +//-------------------------------------------------------------- +void testApp::keyPressed(int key){ + switch (key){ + case '+': + threshold ++; + mogf +=.001; + if (threshold > 255) threshold = 255; + break; + case '-': + threshold --; + mogf-=.001; + if (threshold < 0) threshold = 0; + break; + } +} + +//-------------------------------------------------------------- +void testApp::keyReleased(int key){ + +} + +//-------------------------------------------------------------- +void testApp::mouseMoved(int x, int y ){ + +} + +//-------------------------------------------------------------- +void testApp::mouseDragged(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::mousePressed(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::mouseReleased(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::windowResized(int w, int h){ + +} + +//-------------------------------------------------------------- +void testApp::gotMessage(ofMessage msg){ + +} + +//-------------------------------------------------------------- +void testApp::dragEvent(ofDragInfo dragInfo){ + +} + diff --git a/cvtest/src/testApp.h b/cvtest/src/testApp.h new file mode 100644 index 0000000..4ec8fe5 --- /dev/null +++ b/cvtest/src/testApp.h @@ -0,0 +1,88 @@ +#pragma once + +#include <set> + +#include "ofMain.h" +#include "tesselator.h" + +#include "ofxOpenCv.h" +//#include "ofxOpenCvUtilsForeground.h" +#include <opencv2/opencv.hpp> + +#include "ofxBlobsManager.h" + +#define CAM_WIDTH_FG 640 +#define CAM_HEIGHT_FG 480 + + +class testApp : public ofBaseApp{ + + public: + void setup(); + void update(); + void draw(); + + void keyPressed(int key); + void keyReleased(int key); + void mouseMoved(int x, int y ); + void mouseDragged(int x, int y, int button); + void mousePressed(int x, int y, int button); + void mouseReleased(int x, int y, int button); + void windowResized(int w, int h); + void dragEvent(ofDragInfo dragInfo); + void gotMessage(ofMessage msg); + + int windowWidth, windowHeight; + + ofVideoPlayer vidPlayer; + + //matrix types in ofxOpenCv\libs\opencv\include\opencv2\core\types_c.h + //cv::Mat is dynamic + + //try to accumulate background using SHORT datatype ie CV_16UC / 4 (would 4 be faster, 64 bits) + + cv::Mat accumulator,outmat,output; // background accumulation + + ofxCvColorImage currentFrame; + ofxCvColorImage background; + + ofxCvColorImage mogoutput; + + ofxCvGrayscaleImage grayFrame; + ofxCvGrayscaleImage grayBg; + ofxCvGrayscaleImage grayDiff; + + float learningRate; + bool bFirstFrame; + + ofxCvContourFinder contourFinder; + + float threshold; + + cv::BackgroundSubtractorMOG mog; + + float mogf; + + /* + ofxOpenCvUtilsForeground* fg; + ofxOpenCvUtilsMeanShift* meanShift; + + + ofxCvColorImage blobFrame; + ofxCvColorImage trackFrame; + ofxCvGrayscaleImage resultFrame; + + + + float blockSize; + float minBlobSize; + float maxBlobSize; + float shadowThreshold; + float blur; + bool selectEnabled; + bool useMoG; + bool isTracking; + */ + +}; + |
