Smooth/Slow down drawing for loop/find contours?

Wanted to make a post before my shiny new account got deleted, heh.

Glad to join the community here…really excited to build off everyone’s hard work. I’ve been primarily playing with cvContours and I’ve been trying to get different looks out of drawing the data points. Haven’t touched C++ in years though

Can anyone offer an example or advice on how to sort of slow or smooth the drawing of lines between the different contour points? Or maybe just the terminology of what I’m looking for so I can properly google it, hah. I guess I’m looking for a way to…sort of ‘smooth’ an array of points. I’ve played with just slowing down my drawing for loop by making the count longer, but that obviously just slows down the overall framerate.

I’m mostly playing with the sort of ‘spiderweb’ look when you connect the points to eachother, but the points from findcontours change every frame, so it can be quite jumpy.

Hi,

I don’t understand all what you want, but i use a trick which can be acceptable if you have the same number of points in the same order.

like this:

  
  
float dmpRate = 0.5;  
Point = dmpRate*Point + (1-dmpRate)*newPoint;  
  

More dmpRate you have, the slowest it is.

i use the trick in sound analysis, coming from kylem McDonald in that topic
http://forum.openframeworks.cc/t/ofxfft:-fftw-±kiss-fft-wrapper/2184/36

Good luck

That seems to make sense, but I’m not sure if I’m understanding it correctly. Here is the code snippet where I am drawing:

  
  
for( int i=0; i<(int)contourFinder.blobs.size(); i++ ) {  
		ofNoFill();  
		for (int k=1;k<10;k++){	  
		ofBeginShape();  
			for( int j=0; j<(contourFinder.blobs[i].nPts); j=j+k ) {  
				ofVertex( contourFinder.blobs[i].pts[j].x, contourFinder.blobs[i].pts[j].y );  
				//}  
		ofEndShape();  
		}  
		}  
  
	}  

Putting the damping thing in that of vertex wouldn’t do what I’m thinking…or would it? I tried some of the Penning tweening libraries as well, but no real luck

OF 007 has a few nice methods for working with contour data. they’re all sitting inside ofPolyline.

  
  
ofPolyline getSmoothed(int smoothingSize, float smoothingShape = 0);  
ofPolyline getResampledBySpacing(float spacing);  
ofPolyline getResampledByCount(int count);  
void simplify(float tolerance=0.3);  
  

notice that, except for simplify() they all return a new ofPolyline rather than modifying the current one.

getSmoothed() will smooth your polyline. getResampledBySpacing() will walk along the line and places a vertex every so many pixels (as determined by “spacing”). getResampledByCount() will walk along and evenly place N vertices (as determined by “count”). simplify() will try to remove vertices that are unnecessary. for example, a long line containing lots of vertices with slight deviations will be reduced only to the endpoints.

to use these methods, you just need to convert each blob into a polyline. for example:

  
  
ofPolyline toOf(const ofxCvBlob& blob) {  
	ofPolyline polyline;  
	polyline.addVertexes(blob.pts);  
	return polyline;  
}  
  

this function will convert an ofxCvBlob to an ofPolyline. then inside your draw() you can call that function for each contour, and do smoothing on the returned ofPolyline:

  
  
vector<ofxCvBlob>& blobs = contourFinder.blobs;  
for(int i = 0; i < blobs.size(); i++) {  
	ofPolyline polyline = toOf(blobs[i]);  
	ofPolyline smoothed = polyline.getSmoothed(8);  
	smoothed.draw();  
}  
  

keep in mind that it’s good to disable contour simplification if you’re doing smoothing – or, if the contour is already simplified, make sure you resample it before smoothing.

one of the biggest advantages to using the getSmoothed() method is that it handles the beginning/end part of the contour. if you write a loop as shown in the post above, a circle will turn into a teardrop shape. getSmoothed() will turn the circle into a slightly smaller circle.

Epic…thank you sir, I’ll give that a shot

Hmmm…I’m still stuck on the use of vectors, every time I try and use one myself I seem to miss something. Does anyone have a good place to look more into vectors as they pertain to OF? Still working on relearning pointers too

when I try adding in your code i get errors like this for the line

  
vector<ofxCvBlob>& blobs = contourFinder.blobs();  

Error: '(std::vector<ofxCvBlob, std::allocator >) ()

and then for the line:

  
ofPolyline polyline = toOf(blobs[i]);  

error: no match for call to ‘(ofPolyline) (ofxCvBlob&)’

I’m assuming this is for spatial smoothing, but I’m actually more interested in temporal smoothing…any tips on how to go there with this drawing method?

I usually just look at: http://cplusplus.com/reference/stl/vector/

This error:

  
vector<ofxCvBlob>& blobs = contourFinder.blobs();   

errors because contourFinder.blobs is a property not a method returning a reference. Actually, I don’t even see that in ofxCv. And this:

  
ofPolyline polyline = toOf(blobs[i]);    

should be:

  
ofPolyline polyline = getPolyline(i)  

hope that helps.

Hmm…I’m understanding a little better now. Is there another way to get those memory spaces from contourfinder? Now looking through it seems like the fastest way to work

derp, my fault – josh is exactly right about that first bug in my code. “blobs()” should be “blobs”.

the toOf() is correct though. in the post above i provide a special toOf() function that can be used to convert an ofxCvBlob to ofPolyine. i think the reason josh mentioned getPolyline() is because i have a new opencv addon i’m working on that has a getPolyline() method. all the advice above is for ofxOpenCv.

this way of accessing the blobs:

  
  
vector<ofxCvBlob>& blobs = contourFinder.blobs;  
  

is definitely the fastest. using the & means it’s making a reference (like a nickname) for the data rather than copying it.