ofxCvHaarFinder is horribly slow, any pointers?

#1

so im really playing with the Kinect V1 [& V2 to that effect] & playing with ofxOpenCv works to a great point. but once we bring in things like the ofxCvHaarFinder in, to bolts everything down pretty horribly to a snails pace.
in some ways I feel its my own computer, but things do generally work pretty well, even for its age & specs [which are not bad]

but I did break down the project, just to find what this thing that was slowing it down could be, it is the haar finder.
trying it with the built in camera as well, just in case - still brings slow results, but slightly quicker, even if the resolution is higher

is there any good pointers, or work arounds to utilise it better. or is it a slow thing in general? from seeing other examples/videos of people work in ofxOpenCv, it seems pretty fast. but im sure its just setup more than anything

my setup is as follows:

ofApp.h

ofVideoGrabber grab;
ofxCvColorImage colorImage;
ofxCvGrayscaleImage grayImage;
ofxCvHaarFinder haar;

ofApp.cpp

void ofApp::setup(){
  grab.setup(640, 480);
  
  colorImage.allocate(grab.getWidth(), grab.getHeight());
  grayImage.allocate(grab.getWidth(), grab.getHeight());

  haar.setup("haarcascade_frontalface_default.xml");
}

//--------------------------------------------------------------
void ofApp::update(){
  grab.update();
  
  if (grab.isFrameNew()){
    colorImage.setFromPixels(grab.getPixels());
    grayImage = colorImage;
    haar.findHaarObjects(grayImage);
  }
}

//--------------------------------------------------------------
void ofApp::draw(){
  grab.draw(0, 0);
  
  int faces = haar.blobs.size();
  for (int i = 0; i < faces; i++) {
    float x = haar.blobs[i].boundingRect.x;
    float y = haar.blobs[i].boundingRect.y;
    float w = haar.blobs[i].boundingRect.width;
    float h = haar.blobs[i].boundingRect.height;
    float cx = haar.blobs[i].centroid.x;
    float cy = haar.blobs[i].centroid.y;
    ofSetColor(255);
    ofNoFill();
    ofDrawRectangle(x, y, w, h);
    ofSetColor(255);
    ofDrawBitmapString("face " + ofToString(i), cx, cy);
  }
}

I have taken the kinect stuff out, if anyone else wants to look at. but can easily be put back in & utilised

but I am at a loss in how I can speed this up, so any pointers would be great. links, books, examples, videos etc

thanks

#2

You might try to give it a smaller input image size if you want it to run faster. 640x480 isn’t huge, but it will take some time to process that image. You can crop or resize with ofPixels.

If you want just have a more responsive program, you can move the face detector to a separate thread.

1 Like
#3

on the top of that maybe you should play with maximum and minimum area of a detectable face and it can increase the performance a bit too.
I like to use it in another thread, skip a number of frames without processing (ex: process 1 frame, and not processing other two frames) and interpolating position and area of the rectangles.

    objectFinder.setMinSizeScale( uiFace->pFloat["setMinSizeScale"] );
    objectFinder.setMaxSizeScale( uiFace->pFloat["setMaxSizeScale"] );
    objectFinder.setMinNeighbors( uiFace->pFloat["setMinNeighbors"] );
    objectFinder.setMinNeighbors( 6 );
    objectFinder.setRescale( uiFace->pFloat["setRescale"] );
    objectFinder.setMultiScaleFactor( uiFace->pFloat["setMultiScaleFactor"] );
    objectFinder.setCannyPruning( uiFace->pFloat["setCannyPruning"] );
    objectFinder.setFindBiggestObject( uiFace->pFloat["setFindBiggestObject"] );
    objectFinder.setUseHistogramEqualization( uiFace->pFloat["setUseHistogramEqualization"] );
1 Like