Drawing blob shapes, openCV related.

Hey, all, I’ve got blob detection and tracking working nicely with the openCV addon. But, related to the other questions I’ve been asking, can anyone think of a way I can draw the blob shape from an arbitrary number of frames back in time but using the centriod position of the same blog at the current time?

Maybe if I load a two instances of the moviePlayer and have the second one start after a short delay, then have it draw over the other things being calculated from the first moviePlayer?

Any ideas?

Thanks.

Are you using ofxCvBlobTracker? It gives you nice access to blob ids that you could use to keep track of (in a vector for instance) and use to draw them over time.

I am indeed. Thanks for the reply, I really appreciate it.

I know the vector that contains the blobs is accessible, but does it, or can it, hold every blob found at every frame over the whole animation? Or just the current frame?

I guess I’m a little unclear on what happens to all the data held by any object during the update loop. Is that data destroyed in some way? Take an ofTexture for instance. It gets its color information from a frame of the videoPlayer (for this example). When update occurs, the new frame is run through .getPixels() and dumped into the Texture. Is some kind of clear() command invoked at the top of the update loop? Or are the memory locations of the pixels simply overwritten with new values by getPixels()? I guess I need to create a way to store the information of a frame in some way so it isn’t refreshed away by update.

Any clues would be appreciated. Thanks.

In ofxCvBlobTracker it looks like the blobs are destroyed in the trackBlobs function which you are most likely calling in update

  
void ofxCvBlobTracker::trackBlobs( const vector<ofxCvBlob>& _blobs ) {  
	unsigned int i, j, k;  
  
    // Push to history, clear  
	history.push_back( blobs );  
	if( history.size() > 4 ) {  
		history.erase( history.begin() );  
	}  
	blobs.clear();  

The way I have done it to create a separate Class called TrackingShape

  
  
#include "ofxCvTrackedBlob.h"  
#include "ofxVec2f.h"  
  
class TrackingShape  
{  
public:  
	TrackingShape();  
	~TrackingShape();  
	ofxCvTrackedBlob blob;  
	ofColor color;  
};  

and then in testApp I store them when they show up

  
void testApp::blobOn( int x, int y, int id, int order )  
{	  
	ofxCvTrackedBlob blob = blobTracker.getById( id );  
	 cout << "blobOn() - id:" << id << " order:" << order << "blob.area: " << blob.area<< endl;  
	  
	  
	TrackingShape trackingShape;  
	trackingShape.blob = blob;  
	trackingShape.color = ofColor(ofRandom(0, 255), ofRandom(0, 255), ofRandom(0, 255));  
	trackingShapes.push_back(trackingShape);  
      
	  
	  
}  

This essentially copies the blob before it is destroyed by the ofxCvBlobTracker::trackBlobs function above

So about what is destroyed on update… it depends on the Class. For instance, trackingShapes is declared in testApp.h as

  
vector<TrackingShape> trackingShapes;  

So with vector unless I explicitly call trackingShapes.clear() somewhere they will stay around and be accessible

if I do call trackingShapes.clear() vector will call the destructor ~TrackingShape() on all my TrackingShapes. ~TrackingShape() is something I am responsible for writing to clean up anything I store in the TrackingShape instance.

Thanks! This really helps. I appreciate it very much.

jvcleave–
Thanks also for your suggestion.

Where do you create this class? (Where do you place the code):

  
  
#include "ofxCvTrackedBlob.h"    
#include "ofxVec2f.h"    
    
class TrackingShape    
{    
public:    
    TrackingShape();    
    ~TrackingShape();    
    ofxCvTrackedBlob blob;    
    ofColor color;    
};   
  

In the testApp.h file?

In its own C++ .h file and if so, do you have a .cpp as well?

Thanks for any advice.

I keep it in a separate file TrackingShape.h.

For your purposes you could just put this in your testApp.h after the #includes

  
struct TrackingShape      
{          
    ofxCvTrackedBlob blob;      
    ofColor color;      
};