2013-03-15 13 views
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作为他们自己的私人类成员,然后他们工作正常。但是在主循环中,每当创建线程时,每次加载级联文件对性能来说都不太好。所以我的问题是为什么当线程有共同的级联文件时程序停止?

+0

嗯,你试图把它分成4个补丁?在这种情况下你的号码是错误的(线程b)。另外,为什么只有3个线程/补丁呢?并且它不会工作,因为每个线程只能看到它的一部分 – berak 2013-03-15 10:08:18

+0

我将一帧(图像)分成三部分。在a区域和c区域的分流线上面对面的情况下,线程a为左半部分,线程c为右半部分,线程b。检查Rect()的参数。当线程拥有自己的分类器文件时,这实际上可以很好地工作。 – Barshan 2013-03-15 11:00:36

回答

2

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

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

功能是并行与TBB库。

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

顺便说一句,这thread可以帮助你进一步