2

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

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 作为它们自己的私有类成员时,它们工作正常。但是在主循环中,每当创建线程时,每次加载级联文件似乎对性能没有好处。所以我的问题是为什么当线程有公共级联文件时程序会停止?

4

1 回答 1

3

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

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

该函数与 TBB 库并行化。

因此,您很可能通过从不同线程多次调用 detectMultiScale 来死锁 CascadeClassifier 的唯一实例。

顺便说一句,这个线程可以帮助你进一步

于 2013-03-15T09:59:33.560 回答