【发布时间】:2020-05-02 03:15:52
【问题描述】:
我正在尝试在 QT Creator 的 QLbet 中显示视频。我正在使用 openCV 阅读视频。这是我的代码:
主窗口.cpp
#include "includes.h"
#include "vidreadthread.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
VidReadThread *thread1 = new VidReadThread("Video read thread");
thread1->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
vidreadthread.cpp
#include "vidreadthread.h"
#include "includes.h"
using namespace cv;
extern MainWindow *mainPtr;
VidReadThread::VidReadThread(QString s) : name(s)
{
}
void VidReadThread::run()
{
QThread::msleep(100);
VideoCapture cap;
cap.open("helicopter_with_stickers.mp4");
while(1)
{
Mat image1;
// Capture frame-by-frame
cap >> image1;
// If the frame is empty, break immediately
if (image1.empty())
break;
QImage image2 = QImage((uchar*) image1.data, image1.cols, image1.rows, image1.step, QImage::Format_RGB888);
mainPtr->ui->label1->setPixmap(QPixmap::fromImage(image2));
}
}
我可以显示视频,但无法设置帧速率。整个 60 秒的视频在 4-5 帧内结束。仅使用 OpenCV,我可以使用 cvWaitkey() 来控制帧速率,但这里的 msleep() 似乎不适用于类似的应用程序。请提出一种不跳帧的方法。我创建了一个vidreadthread,这样在读取视频时 GUI 就不会挂起。
如果有任何其他方式可以在我的 QT UI 中显示 OpenCV 窗口,那么也请推荐。
【问题讨论】:
-
如果您选择 Qml(Qt Quick) ,我可以建议 2 种不同的方式以及与 opencv 直接相关的示例。我知道如何使用 Qt Quick App。但我不知道 Qt Widget 应用程序。
-
你的
msleep()在循环之外,所以它肯定不会影响帧率。此外,您正在从另一个线程访问QLabel指针,而没有确保没有其他人正在访问它(例如通过关键部分),因此您在这里也受到竞争条件的影响。 -
@Fareanor 只是因为好奇。我还在另一个线程中使用循环从相机中获取帧。我正在使用全局静态 qimage 到达线程循环中的帧。因为您说“没有其他人在访问..”还是我误解了?我想他也可以访问它
-
@YunusTemurlenk 实际上,如果多个线程/进程同时访问内存中的同一位置,则行为是未定义的(任何事情都可能发生)。这就是为什么您需要诸如互斥锁、信号量等之类的东西,以便在工作人员读取/写入共享变量时自动锁定对共享变量的访问。你可以先看看this
-
我的经验表明,从另一个线程更新小部件并不是一个好的解决方案!所以在线程和主线程中发出一个信号,只要 Mat 准备好将它传递给主线程
标签: c++ qt opencv image-processing video-processing