Ask Your Question
1

OpenCV CascadeClassifier Segmentation Fault

asked 2013-07-27 08:27:16 -0600

bonchenko gravatar image

updated 2013-07-28 22:46:40 -0600

This is same question I asked in StackOverflow

I am using OpenCV to detect faces in video. Currently I am using CascadeClassifier class, Haar classifier. When I run cascade.detectmultiscale, my program will run normally and suddenly crash with segmentation fault. I debug using gdb and found out thatProgram received signal SIGSEGV, Segmentation fault.

[Switching to Thread 0xb1841460 (LWP 995)]
0x00099280 in cvRunHaarClassifierCascadeSum(CvHaarClassifierCascade const*, CvPoint, double&, int) () there is problem in cvRunHaarClassifierCascadeSum

Running backtrace, seems like gdb cannot finish the process

#0  0x00099470 in cvRunHaarClassifierCascadeSum(CvHaarClassifierCascade const*, CvPoint, double&, int) ()
#1  0x0009a8be in cvRunHaarClassifierCascade ()
#2  0x0009b28e in cv::HaarDetectObjects_ScaleCascade_Invoker::operator()(cv::Range const&) const ()
#3  0x00175928 in tbb::interface6::internal::start_for<tbb::blocked_range<int>, (anonymous namespace)::ProxyLoopBody, tbb::auto_partitioner con)
()
#4  0x00502f5e in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::local_wait_for_all(tbb::task&, tbb::task*) ()
#5  0x005037d0 in tbb::internal::arena::process(tbb::internal::generic_scheduler&) ()
#6  0x00506c60 in tbb::internal::market::process(rml::job&) ()
#7  0x005078fe in tbb::internal::rml::private_worker::run() ()
#8  0x00507c3a in tbb::internal::rml::private_worker::thread_routine(void*) ()
#9  0xb6fb1cb0 in start_thread () from /usr/lib/libpthread.so.0
#10 0xb6dd6828 in ?? () from /usr/lib/libc.so.6
#11 0xb6dd6828 in ?? () from /usr/lib/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

I tried using the C version of cascade classifier ( the CvHaarClassifierCascade class ), same problem also happens when I run it and debug it. This is the code in case you want to see my implementation:

Detector class

class faceDetector {
    ...
    cv::CascadeClassifier cascade;
    ...
};

Initialization

int initDetector(faceDetector* detect) {
    detect->cascade.load( CASCADE_XML_PATH );
    detect->flags = CV_HAAR_DO_CANNY_PRUNING;
    detect->maxR = 23;
    detect->minNeighbours = 3;
    detect->minSize = cvSize(10, 10);
    detect->maxSize = cvSize(100, 100);
    detect->scaleFactor = 1.1;
    cout << "initDetection finished " << endl;
    return 1;
}

Detection, called in a while loop

int faceDetector::detectFaces(IplImage* img, CvRect** regions) {
    int nFaces = 0; // number of detection considered as face
    IplImage* gray = cvCreateImage( cvSize(img->width, img->height), 8, 1 );
    IplImage* smallImg = cvCreateImage( cvSize( cvRound (img->width/scaleFactor),
                                            cvRound (img->height/scaleFactor)), 8, 1 );
    cvCvtColor(img, gray, CV_BGR2GRAY);
    cvResize(gray, smallImg, CV_INTER_LINEAR);
    cvEqualizeHist(smallImg, smallImg);
    cvClearMemStorage(storage);
    int nx1, nx2, ny1, ny2; // coordinate of detection rectangles

    std::vector<cv::Rect> faces; // list of detection
    cv::Mat msmallimg(smallImg);
    cascade.detectMultiScale( msmallimg, faces, scaleFactor, minNeighbours, flags, minSize, maxSize );

    CvRect* nRects;
    nRects = (CvRect*) malloc(faces.size() * sizeof(CvRect));

    std::vector<cv::Rect>::const_iterator i;

    for (i=faces.begin(); i!=faces.end() ; ++i) {
        if ((i->width <= maxSize.width) && (i->height <= maxSize.height) && (i->width >= minSize.width) && (i->height >= minSize.height) ) {
            nx1 = cvRound( i->x * scaleFactor);
            ny1 = cvRound( i->y * scaleFactor);
            nx2 = cvRound( (i->x + i->width) * scaleFactor);
            ny2 = cvRound( (i->y + i->height) * scaleFactor);           
            nRects[nFaces] = cvRect(nx1, ny1, nx2-nx1, ny2-ny1);
            nFaces++;
        }
    }

    *regions = nRects;
    cvReleaseImage(&gray);
    cvReleaseImage(&smallImg);
    return nFaces;
}

The error always happened after I call

cascade.detectMultiScale( msmallimg, faces, scaleFactor, minNeighbours, flags, minSize, maxSize );

Is this known bugs in OpenCV cascade classifier or I have a bad code? I am confused how to debug further on this problem because it ... (more)

edit retag flag offensive close merge delete

Comments

Today I tried recompile OpenCV without TBB library, and application runs smoothly. I am thinking this is related to parallelization by TBB. I still looking forward to the solution because without TBB, the application runs 2-3x slower :(

bonchenko gravatar imagebonchenko ( 2013-07-29 01:16:48 -0600 )edit

First of all, try skipping the C -style API and move on to the C++ style API, because your problem could be focussed right there.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-07-29 03:25:25 -0600 )edit

Thanks Steve. I tried your suggestion, changing the all of the code to C++, and still the same problem happened. I get segmentation fault in cascade.detectMultiScale. The gdb and the backtrace is same. Interestingly, I recompile OpenCV without tbb, and the problem vanished... Unfortunately, this cause my application to run 2-3 x slower

bonchenko gravatar imagebonchenko ( 2013-07-30 01:55:28 -0600 )edit

What TBB version are you using? As far as I know, TBB 4.1.3 is used with OpenCV2.4.6 It could be that you are using an old version of it? Also, change your post code with the C++ interface, so we can have a look at it.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-07-30 02:00:49 -0600 )edit

I realize this is a year and a half later, but I just wanted to say that I'm having the exact same issue (running Ubuntu 14.04 on Odroid XU3, and I compiled OpenCV for multithreading ((and I'm using the C++ interface to OpenCV)).

slycheese gravatar imageslycheese ( 2014-12-03 17:01:09 -0600 )edit

I am also having the same crash or very large rect.size() returned. I am using 1280x720 image.

richardgohth gravatar imagerichardgohth ( 2016-01-18 02:05:57 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2013-07-30 05:50:02 -0600

bonchenko gravatar image

I do cannot recall the TBB version, all I know is I compile OpenCV with BUILD_TBB and WITH_TBB flag on, in console I see it download a tbb archive which I cannot recall the version. This is my C++ implementation:

Detector class

class faceDetector {
    ...
    cv::CascadeClassifier cascade;
    ...
};

Initialization

int initDetector(faceDetector* detect) {
    detect->cascade.load( CASCADE_XML_PATH );
    detect->flags = CV_HAAR_DO_CANNY_PRUNING;
    detect->maxR = 23;
    detect->minNeighbours = 3;
    detect->minSize = cvSize(10, 10);
    detect->maxSize = cvSize(100, 100);
    detect->scaleFactor = 1.1;
    cout << "initDetection finished " << endl;
    return 1;
}

Detection, called in a while loop

int adaboostDetect::detectObject(Mat img, Rect* regions) {
    int nHeads = 0;

    cv::Mat gray( img.size(), CV_8UC1, cv::Scalar::all(0) );
    cv::Mat smallImg( cv::Size( cvRound (img.cols/scaleFactor),
                            cvRound (img.rows/scaleFactor)), CV_8UC1, cv::Scalar::all(0) );

    cvtColor(img, gray, CV_BGR2GRAY);
    cv::resize(gray, smallImg, smallImg.size(), CV_INTER_LINEAR);
    equalizeHist(smallImg, smallImg);
    int nx1, nx2, ny1, ny2;
    std::vector<cv::Rect> faces;
    cascade.detectMultiScale( smallImg, faces, scaleFactor, minNeighbours, flags, minSize, maxSize );
    std::vector<cv::Rect>::const_iterator i;

    for (i=faces.begin(); i!=faces.end() ; ++i) {
        if ((i->width <= maxSize.width) && (i->height <= maxSize.height) && (i->width >= minSize.width) && (i->height >= minSize.height) ) {
            nx1 = cvRound( i->x * scaleFactor);
            ny1 = cvRound( i->y * scaleFactor);
            nx2 = cvRound( (i->x + i->width) * scaleFactor);
            ny2 = cvRound( (i->y + i->height) * scaleFactor);
            *regions = Rect(nx1, ny1, nx2-nx1, ny2-ny1);
            regions++;
            nHeads++;
        }
    }
    return nHeads;
}
edit flag offensive delete link more

Comments

Download TBB yourself first, not using the default package that gets downloaded. Then supply links to the corresponding TBB you installed in your CMAKE. That is how i got it work!

StevenPuttemans gravatar imageStevenPuttemans ( 2013-07-30 05:58:25 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2013-07-27 08:27:16 -0600

Seen: 2,536 times

Last updated: Jul 30 '13