多线程人脸检测停止工作

时间:2013-03-15 09:44:12

标签: multithreading qt opencv qthread

我正在尝试实现多线程人脸检测器。问题是从相机捕获和处理一些帧后,程序意外停止工作。这是代码:

cascadeClassifier cad;

class myThread: public QThread
{
private:
    Mat threadRoi;
    vector<Rect> faces;
protected:
    void run()
    {
        cad.detectMultiScale(threadRoi,faces,1.4,4,CV_HAAR_DO_CANNY_PRUNING|CV_HAAR_FIND_BIGGEST_OBJECT,Size(30,30));
        if ( !faces.empty())
                  rectangle(threadRoi,faces[0],Scalar(0,255,0),2);
    }
public:
    myThread(Mat &r)
    {
        threadRoi = r;
    }
    vector<Rect> getFaces()
    {
        return faces;
    }
};
int main()
{
    cad.load("C:/opencv/data/lbpcascades/lbpcascade_frontalface.xml");
    VideoCapture cap(0);
    Mat frame;
    while(1)
    {
       if(!cap.read(frame))   break;
       cvtColor(frame,frame_gray));
       myThread a(frame_gray(Rect(0,0,frame.cols/2,frame.rows/2));
       myThread b(frame_gray(Rect(frame.cols/4,0,frame.cols/2,frame.rows/2));
       myThread c(frame_gray(Rect(frame.cols/2,0,frame.cols/2,frame.rows/2));
       a.start();
       b.start();
       c.start();
       a.wait();
       b.wait();
       c.wait();
    }
    return 0;
}

我注意到如果我为所有线程使用通用的cascadeClassifier,则会出现此问题。当我给每个线程分开cascadeClassifiers作为他们自己的私人类成员然后他们工作正常。但是在主循环中,无论何时创建线程,每次加载级联文件似乎都不利于性能。所以我的问题是当线程有共同的级联文件时程序停止的原因?

1 个答案:

答案 0 :(得分:3)

似乎有死锁。我怀疑CascadeClassifier :: detectMultiScale函数负责。首先,你有一个和几个线程的相同的cascadeClassifier 。当这些线程调用detectMultiScale时,它们会在相同的实例上调用它。 (这就像在不同的线程中使用相同的文件句柄,其中所有操作都转到同一个文件。)

进一步的detectMultiScale已经是多线程/并行化的。 在docs中说

  

该功能与TBB库并行化。

所以你很可能通过从不同的线程多次调用detectMultiScale来锁定CascadeClassifier的唯一实例。

顺便说一下,thread可以帮助您进一步