Using ofxCvContourFinder's findContours

Hi again,

Here’s the second project/problem. It’s about using openCV to get image contours of pictures, so I read the documentation and the example of ofxCvContourFinder’s findContours function which seems that it’s what I’m looking for but I must be using it wrong.

As I understand, it returns the number of blobs found, and then you add them to a polyline object to draw each contour line found.

myImage.loadImage ("appelbaum1.png");
grayImage.setFromPixels(myImage.getPixels(), 1039, 585);
contourFinder.findContours(grayImage, 1039 * 585, ofGetWindowWidth() * ofGetWindowHeight(), 1200, false, true);
polylines.clear();
for(unsigned int i = 0; i < contourFinder.blobs.size(); i++) {
    ofPolyline cur;
    // add all the current vertices to cur polyline
    cur.addVertices(contourFinder.blobs[i].pts);
    cur.setClosed(true);
    
    // add the cur polyline to all these vector<ofPolyline>
    polylines.push_back(cur);
}

And then in the draw function I just draw each polyline:

ofBackground(0);

ofSetColor(255);
for (int i = 0; i < polylines.size(); ++i) {
    polylines[i].draw();
}

but nothing shows up on the window. I’ve tried to do a

contourFinder.draw();

instead of that for loop but nothing is shown.

What I’m missing here ?

Thanks for the help,

DarthRivan

I haven’t tried your code, but you will get much better results if you process the image a bit before you call findContours so that the shapes stand out more. Specifically, threshold it and then maybe some blur, erode, dilate. If you post the image(s) you are trying to use I can suggest a specific solution. Are you trying to find Jacob Appelbaum?

Yes, it’s Jacob (this photo) and I want to add more people like Aaron Swartz and other people related but now I’m just trying to find the contour of this image and then add more to the animation.

I really have no clue on image processing so I don’t know what threshold, erode or dilate can do to an image. As you said, I probably have to process it in order to make the contours more visible for the function although I don’t know where to start.

Here is a start.

declare some stuff in ofApp.h

ofxCvColorImage colorImage;
ofxCvGrayscaleImage grayImage;
ofxCvGrayscaleImage thresholdImage;
ofxCvContourFinder 	contourFinder;

ofApp.cpp

//--------------------------------------------------------------
void ofApp::setup(){
    
    ofImage image;
    image.loadImage("appelbaum1.png"); // load in your image
    image.setImageType(OF_IMAGE_COLOR); // get rid of alpha channel from png
    
    ofSetWindowShape(image.getWidth(), image.getHeight());
    
    colorImage.setFromPixels(image.getPixelsRef()); // put the pixels into the image format openCV understands

    grayImage = colorImage;  // convert the image to grayscale using the handy overloaded operator
    thresholdImage = grayImage; // make a copy for thresholding
    
    thresholdImage.threshold(100); // turn any pixels above 100 white, and below 100 black

    
    int totalArea = thresholdImage.width*thresholdImage.height;
    int minArea = totalArea * 0.001;
    int maxArea = totalArea * 0.75;
    int nConsidered = 10;

    contourFinder.findContours(thresholdImage, minArea, maxArea, nConsidered, true);
}
     

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){
    ofSetColor(ofColor::white);
    thresholdImage.draw(0, 0);  
    for (int i = 0; i < contourFinder.nBlobs; i++){
        ofxCvBlob& blob = contourFinder.blobs[i];
        blob.draw(0, 0);
    }
    
    ofSetColor(ofColor::red);
    ofDrawBitmapString("nBlobs="+ofToString(contourFinder.nBlobs), 10, 15);
}