基本理念
我正在开发一个带有4个USB摄像头的应用程序,必须从所有这些摄像头中取出帧,并以最佳fps显示在QLabel中。
即使我的处理器只有20%的利用率,从所有摄像机中逐帧获取帧也会导致帧速率降低。
我认为如何提高帧率?
使用多线程可以增加CPU利用率,并且可以有 4个线程每个从各个摄像头获取图像,发送信号并将图像发送回GUI线程(主线程)将显示图像转换为适当的标签。
当前设计:基于https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
Thread类继承自QObject,方法为:
class fetchCam1 : public QObject
{
Q_OBJECT
public:
fetchCam1(cv::VideoCapture cap);
~fetchCam1();
public slots:
void process();
cv::Mat returnCamFrame();
signals:
void finished();
};
其实施:
fetchCam1::fetchCam1(cv::VideoCapture cap)
{
this->cap = cap;
}
cv::Mat fetchCam1::returnCam1Frame()
{
return src;
}
void fetchCam1::process() {
// allocate resources using new here
cap.read(src);
emit finished();
}
在Main(GUI)线程中启动线程和辅助角色:
The captureS1..S4, Is the VideoCapture object, also fetchCam1* worker1-4,
QThread* thread1-4; are defined as global variables.
thread1 = new QThread;
worker1 = new fetchCam1(captureS1);
worker1->moveToThread(thread1);
connect(thread1, SIGNAL(started()), worker1, SLOT(process()));
connect(worker1, SIGNAL(finished()), this, SLOT(updateCam1()));
connect(worker1, SIGNAL(finished()), worker1, SLOT(process()));
thread1->start();
thread2 = new QThread;
worker2 = new fetchCam1(captureS2);
worker2->moveToThread(thread2);
connect(thread2, SIGNAL(started()), worker2, SLOT(process()));
connect(worker2, SIGNAL(finished()), this, SLOT(updateCam2()));
connect(worker2, SIGNAL(finished()), worker2, SLOT(process()));
thread2->start();
thread3 = new QThread;
worker3 = new fetchCam1(captureS3);
worker3->moveToThread(thread3);
connect(thread3, SIGNAL(started()), worker3, SLOT(process()));
connect(worker3, SIGNAL(finished()), this, SLOT(updateCam3()));
connect(worker3, SIGNAL(finished()), worker3, SLOT(process()));
thread3->start();
thread4 = new QThread;
worker4 = new fetchCam1(captureS4);
worker4->moveToThread(thread4);
connect(thread4, SIGNAL(started()), worker4, SLOT(process()));
connect(worker4, SIGNAL(finished()), this, SLOT(updateCam4()));
connect(worker4, SIGNAL(finished()), worker4, SLOT(process()));
thread4->start();
每个都调用:
void MainWindow::updateCam1()
{
cv::Mat src = worker1->returnCamFrame();
QPixmap pixg = convertFromMat(src);
ui->label_4s1->setPixmap(pixg);
}
void MainWindow::updateCam2()
{
cv::Mat src = worker1->returnCamFrame();
QPixmap pixg = convertFromMat(src);
ui->label_4s2->setPixmap(pixg);
}
void MainWindow::updateCam3()
{
cv::Mat src = worker1->returnCamFrame();
QPixmap pixg = convertFromMat(src);
ui->label_4s3->setPixmap(pixg);
}
void MainWindow::updateCam4()
{
cv::Mat src = worker1->returnCamFrame();
QPixmap pixg = convertFromMat(src);
ui->label_4s4->setPixmap(pixg);
}
请帮我辨别我做错了什么?上面的代码确实启动并加载了前几帧,之后程序崩溃,没有任何错误。
此外,如果只使用一个线程从一个摄像头获取图像,则上述代码效果很好。
实施此方法的正确方法是什么?谢谢。
更新 崩溃:
我相信所有4台摄像机的帧都被快速取出,并且这会产生太多信号供主线程处理,这会导致溢出导致崩溃。 我相信某种同步可以帮助但我怎么能去做呢?