我正在尝试创建一个QTCreator视频流应用程序,我希望它能够在我想要的FPS上显示当前帧,同时保持同时获取新帧,并且能够查看以前的帧和下一帧同样,非常像视频播放器中的前进和后退按钮。
为此,我正在使用类cv::Mat
将从VideoCapture
对象收到的QImage
对象转换为Player
。
Player
对象尽可能快地生成QImages:
cv::cvtColor(frame, RGBframe, CV_BGR2RGB);
img = QImage((const unsigned char*)(RGBframe.data),
RGBframe.cols,RGBframe.rows,RGBframe.step,QImage::Format_RGB888);
在此之后,Player
会发出一个信号:
emit originalImage(img);
此信号在MainWindow中连接为:
connect(player, SIGNAL(originalImage(QImage)), this,
SLOT(updateDisplay(QImage)));
从updateDisplay
开始,我将QImage
推送到QVector<QImage>
向量,该向量充当缓冲区,位于单独的类Display
中,我用它来处理帧我想要:
void MainWindow::updateDisplay(QImage img){
if(!img.isNull)
display->push(img)
}
在Display
课程中:
void Display::push(QImage image){
mutex.lock();
buffer.push_back(image);
mutex.unlock();
}
Display
和Player
都是线程。在Display::run()
,我正在尝试使用我想要的速度更新QLabel
中的MainWindow
。问题是,在我的buffer
对象中,当我推送新值时,先前的值会发生变化。在run方法中,我尝试在循环中执行以下操作:
if(!buffer.isEmpty()){
QImage curr = buffer.at(0);
label->setAlignment(Qt::AlignCenter);
label->setPixmap(QPixmap::fromImage(curr).scaled(label->size(),
Qt::KeepAspectRatio, Qt::FastTransformation));
msleep(100);
}
msleep
用于以10 FPS显示图像。这应该继续使用相同的QImage
更新标签,这是首先推入buffer
的标签,但这就是我的问题所在。当我测试它时,标签会不断变化并显示推入缓冲区的最新图像,即使它应该显示静态图像。