Drawing perpendicular lines to shapes in live video

I’m playing around with an idea to generate animations that appear to ‘grow’ from the edges of shapes in live video, and could use some advice. I know that the essence of what I’m trying to do looks a lot like drawing normals in OpenGL, but I’m not sure how to translate that idea into a 2D image space.

I know that using OpenCV one can easily draw outlines of shapes using the findContours method of ofxCvContourFinder, but how about drawing lines that are perpendicular to the edges that are found?

Here is an example of what I am trying to describe: http://imgur.com/pR97B

hey this is a fun challenge and will have a really nice effect.

So say you have a vector points; that is the contour. You can look the OpenCV example showing you how to get this. If you want to draw the perpendiculars, you’ll need to do a little vector math.

the idea is to walk along each pair of two points and get the direction vector between them, then get the perpendicular to that direction vector and draw the line

  
  
vector<ofPoint> points; //full of contour points  
float length = 10; //defines how long the perpendicular lines are.  
for(int i = 0; i < points.size()-1; i++){  
    ofVec2f perpendicular = ofVec2f( (points[i+1] - points[i]) ).getPerpendicular() * length;  
    ofLine(points[i], points[i]+perpendicular);  
}  
  

If the normals are pointing inwards instead of outward, just invert the perpendicular vector with a negative.

Looking good to me! I did not realize that ofxCvBlob objects contained vectors of their outlining contours, very useful. And that ofVec2f.getPerdicular method just makes me feel so stupid :stuck_out_tongue:

However, for me the ofLine method only accepts x/y float pairs (x1, y1, x2, y2) rather than ofPoint objects. I am still using 0062, maybe I should upgrade to 007?

No big deal though, I just used my intuition and got it working :slight_smile: Here is my code in case anyone comes across this thread in the future wondering the same thing:

  
    for(int i=0; i<contourFinder.nBlobs; i++) {  
        vector<ofPoint> points = contourFinder.blobs[i].pts;  
        for(int j=0; j<points.size()-1; j++) {  
            ofxVec2f perp = ofxVec2f( (points[j+1] - points[j]) ).getPerpendicular() * 10;  
            ofPoint p2 = points[j] + perp;  
            ofLine(points[j].x, points[j].y, p2.x, p2.y);  
        }  
    }  

The keys to getting this figured out are a) knowing that you can break up blobs into vectors of points describing the outline of the blob and b) using the .getPerpendicular() method of ofxVec2f.

By the way obviousjim, I am a big fan of your work :slight_smile: I’m a graduate student in Nebraska and find it somewhat hard to explain to people in my area what kinds of work I respect, and your “Voyagers” piece is always one of the first things I show them and say, “Someday, I want to create work like THIS” :stuck_out_tongue: Also, massive props for creating ofxaddons.com, that’s one big thing missing from the oF canon (that and better documentation overall).

Hey h4t,

Thanks for the kind words =) yeah hopefully these documentation efforts that the team is putting together right now will pay off and we’ll have some awesome documentation soon!

Your solution looks perfect – nice work! It’s up to you if you want to upgrade to 007, for stuff like this it’s helpful to have the more flexible functions for things like ofLine that take more types of parameters.

One thing i thought about with your project is you can choose whether to simplify your contours along straight lines or not with the bUseApproximation param to findContours.

If you force this to false you’ll get more points and more evenly distributed normals.

Also if you want to get tricky you can make more than one normal per segment, and use angle interpolation to make them smoothly transition between one to the next so that it makes them appear somewhat curved, and smooth. Kind of like normal interpolation for phong shading:

http://en.wikipedia.org/wiki/Phong-shading

Just some fun stuff to think about. Happy hacking!