I actually have it set so that only 1 blob is detected at a time. I’ve commented where i do that in the code below. Good call on the no blobs part however, as I will have to use the mouse coordinates as a fallback if number of blobs = 0.
Here is my entire code at the time. I can move the mouse and rotate the object, but not with the blobs yet.
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
#ifdef _USE_LIVE_VIDEO
vidGrabber.setVerbose(true);
vidGrabber.initGrabber(320,240);
#else
vidPlayer.loadMovie("fingers.mov");
vidPlayer.play();
#endif
colorImg.allocate(320,240);
grayImage.allocate(320,240);
grayBg.allocate(320,240);
grayDiff.allocate(320,240);
bLearnBakground = true;
threshold = 60;
//for smooth animation
ofSetVerticalSync(true);
//turn on alpha blending for colors
ofEnableAlphaBlending();
//load some obj files from disk
crane.loadFile("crane.obj");
bMousePressed = false;
}
//--------------------------------------------------------------
void testApp::update(){
ofBackground(100,100,100);
bool bNewFrame = false;
#ifdef _USE_LIVE_VIDEO
vidGrabber.grabFrame();
bNewFrame = vidGrabber.isFrameNew();
#else
vidPlayer.idleMovie();
bNewFrame = vidPlayer.isFrameNew();
#endif
if (bNewFrame){
#ifdef _USE_LIVE_VIDEO
colorImg.setFromPixels(vidGrabber.getPixels(), 320,240);
#else
colorImg.setFromPixels(vidPlayer.getPixels(), 320,240);
#endif
grayImage = colorImg;
if (bLearnBakground == true){
grayBg = grayImage; // the = sign copys the pixels from grayImage into grayBg (operator overloading)
bLearnBakground = false;
}
// take the abs value of the difference between background and incoming and then threshold:
grayDiff.absDiff(grayBg, grayImage);
grayDiff.threshold(threshold);
// find contours which are between the size of 20 pixels and 1/3 the w*h pixels.
// also, find holes is set to true so we will get interior contours as well....
contourFinder.findContours(grayDiff, 20, (340*240)/3, 1, false, false);
// ^ only 1 blob detected
//int TheX = contourFinder.blobs[i].centroid.x;
//int TheY = contourFinder.blobs[i].centroid.y;
}
printf("%f \n", ofGetFrameRate());
}
//--------------------------------------------------------------
void testApp::draw(){
// draw the incoming, the grayscale, the bg and the thresholded difference
ofSetColor(0xffffff);
colorImg.draw(20,20);
grayImage.draw(360,20);
grayBg.draw(20,280);
grayDiff.draw(360,280);
// then draw the contours:
ofFill();
ofSetColor(0x333333);
ofRect(360,540,320,240);
ofSetColor(0xffffff);
// we could draw the whole contour finder
//contourFinder.draw(360,540);
// or, instead we can draw each blob individually,
// this is how to get access to them:
for (int i = 0; i < contourFinder.nBlobs; i++){
contourFinder.blobs[i].draw(360,540);
//draws a circle around the center of the blob in the color image.
ofCircle(contourFinder.blobs[i].centroid.x, contourFinder.blobs[i].centroid.y, 20);
}
// finally, a report:
ofSetColor(0xffffff);
char reportStr[1024];
sprintf(reportStr, "bg subtraction and blob detection\npress ' ' to capture bg\nthreshold %i (press: +/-)\nnum blobs found %i", threshold, contourFinder.nBlobs);
ofDrawBitmapString(reportStr, 20, 600);
ofSetupScreen();
//draw in middle of the screen
glTranslatef(ofGetWidth()/2,ofGetHeight()/2,0);
//tumble according to mouse
glRotatef(mouseY,1,0,0);
glRotatef(mouseX,0,1,0);
//scale large enough to see the model
float s = min(ofGetWidth(),ofGetHeight())*0.2; //default is 0.4
glScalef(s,s,s);
if (bMousePressed == false){
//draw the model
glColor4f(0.5,1,5,0.4);//lime color
crane.fillFaces();//first the faces
glColor4f(0,0.8,0,1);//outline
crane.outlineFaces();//then the edges.
} else {
//glColor4f(0,0.1,0,0.5);//outline
//crane.outlineFaces();//then the edges.
//wanna see the vertices?
glColor4f(1,0,0,0.85);
glPointSize(50);
crane.pointVertices();
}
}
//--------------------------------------------------------------
void testApp::keyPressed (int key){
switch (key){
case ' ':
bLearnBakground = true;
break;
case '+':
threshold ++;
if (threshold > 255) threshold = 255;
break;
case '-':
threshold --;
if (threshold < 0) threshold = 0;
break;
}
}
//--------------------------------------------------------------
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(){
}