gpt4 book ai didi

linux - 将现有的 OpenCV 应用程序包含到 Qt GUI 中

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:24:34 26 4
gpt4 key购买 nike

我想将现有的 openCV 应用程序包含到使用 Qt 创建的 GUI 中。我在 stackoverflow 上发现了一些类似的问题

QT How to embed an application into QT widget

Run another executable in my Qt app

问题是,我不想像使用 QProcess 那样简单地启动 openCV 应用程序。OpenCV 应用程序有一个“MouseListener”,所以如果我点击窗口,它应该仍然调用 openCV App 的功能。我还想在 Qt GUI 的标签中显示检测到的坐标。因此它必须是某种交互。

我已经阅读了有关 createwindowContainer 函数 ( http://blog.qt.io/blog/2013/02/19/introducing-qwidgetcreatewindowcontainer/ ) 的信息,但由于我对 Qt 不是很熟悉,所以我不确定这是否是正确的选择以及如何使用它。

我使用的是 Linux Mint 17.2、opencv 3.1.0 版和 Qt 4.8.6 版

谢谢你的意见

最佳答案

我一开始并没有真正按照我想要的方式解决问题。但现在它正在工作。如果有人有同样的问题,也许我的解决方案可以提供一些想法。如果您想在 qt 中显示视频,或者如果您对 OpenCV 库有疑问,也许我可以提供帮助。

以下是一些代码片段。他们没有太多评论,但我希望这个概念很清楚:

首先,我有一个带有标签的主窗口,我将其提升为我的 CustomLabel 类型。 CustomLabel 是我的容器,用于显示视频并对我的鼠标输入作出 react 。

CustomLabel::CustomLabel(QWidget* parent) : QLabel(parent), currentImage(NULL), 
tickrate_ms(33), vid_fps(0), video_width(0), video_height(0), myTimer(NULL), cap(NULL)
{
// init variables
showPoints = true;
calculatedCenter = cv::Point(0,0);
oldCenter = cv::Point(0,0);
currentState = STATE_NO_STREAM;
NOF_corners = 30; //default init value
termcrit = cv::TermCriteria(cv::TermCriteria::COUNT | cv::TermCriteria::EPS, 30,0.01);
// enable mouse Tracking
this->setMouseTracking(true);
// connect signals with slots
QObject::connect(getMainWindow(), SIGNAL(sendFileOpen()), this, SLOT(onOpenClick()));
QObject::connect(getMainWindow(), SIGNAL(sendWebcamOpen()), this, SLOT(onWebcamBtnOpen()));
QObject::connect(getMainWindow(), SIGNAL(closeVideoStreamSignal()), this, SLOT(onCloseVideoStream()));
}

您必须覆盖 paintEvent-Method:

void CustomLabel::paintEvent(QPaintEvent *e){
QPainter painter(this);

// When no image is loaded, paint the window black
if (!currentImage){
painter.fillRect(QRectF(QPoint(0, 0), QSize(width(), height())), Qt::black);
QWidget::paintEvent(e);
return;
}

// Draw a frame from the video
drawVideoFrame(painter);

QWidget::paintEvent(e);
}

在 paintEvent 中调用的方法:

void CustomLabel::drawVideoFrame(QPainter &painter){
painter.drawImage(QRectF(QPoint(0, 0), QSize(width(), height())), *currentImage,
QRectF(QPoint(0, 0), currentImage->size()));
}

在我的计时器的每一个滴答声中我调用 onTick()

void CustomLabel::onTick() {
/* This method is called every couple of milliseconds.
* It reads from the OpenCV's capture interface and saves a frame as QImage
* the state machine is implemented here. every tick is handled
*/
if(cap->isOpened()){
switch(currentState) {
case STATE_IDLE:
if (!cap->read(currentFrame)){
qDebug() << "cvWindow::_tick !!! Failed to read frame from the capture interface in STATE_IDLE";
}
break;
case STATE_DRAWING:
if (!cap->read(currentFrame)){
qDebug() << "cvWindow::_tick !!! Failed to read frame from the capture interface in STATE_DRAWING";
}
currentFrame.copyTo(currentCopy);
cv::circle(currentCopy, cv::Point(focusPt.x*xScale, focusPt.y*yScale),
sqrt((focusPt.x - currentMousePos.x())*(focusPt.x - currentMousePos.x())*xScale*xScale+(focusPt.y - currentMousePos.y())*
(focusPt.y - currentMousePos.y())*yScale*yScale), cv::Scalar(0, 0, 255), 2, 8, 0);
//qDebug() << "focus pt x " << focusPt.x << "y " << focusPt.y;
break;
case STATE_TRACKING:
if (!cap->read(currentFrame)){
qDebug() << "cvWindow::_tick !!! Failed to read frame from the capture interface in STATE_TRACKING";
}
cv::cvtColor(currentFrame, currentFrame, CV_BGR2GRAY, 0);
if(initGrayFrame){
currentGrayFrame.copyTo(previousGrayFrame);
initGrayFrame = false;
return;
}
cv::calcOpticalFlowPyrLK(previousGrayFrame, currentFrame, previousPts, currentPts, featuresFound, err, cv::Size(21, 21),
3, termcrit, 0, 1e-4);
AcquireNewPoints();
currentCopy = CalculateCenter(currentFrame, currentPts);
if(showPoints){
DrawPoints(currentCopy, currentPts);
}
break;
case STATE_LOST_POLE:
currentState = STATE_IDLE;
initGrayFrame = true;
cv::cvtColor(currentFrame, currentFrame, CV_GRAY2BGR);
break;
default:
break;
}
// if not tracking, draw currentFrame
// OpenCV uses BGR order, convert it to RGB
if(currentState == STATE_IDLE) {
cv::cvtColor(currentFrame, currentFrame, CV_BGR2RGB);
memcpy(currentImage->scanLine(0), (unsigned char*)currentFrame.data, currentImage->width() * currentImage->height() * currentFrame.channels());
} else {
cv::cvtColor(currentCopy, currentCopy, CV_BGR2RGB);
memcpy(currentImage->scanLine(0), (unsigned char*)currentCopy.data, currentImage->width() * currentImage->height() * currentCopy.channels());
previousGrayFrame = currentFrame;
previousPts = currentPts;
}
}
// Trigger paint event to redraw the window
update();
}

不要介意 yScale 和 xScale 因素,它们只是用于 opencv 绘图功能,因为 customLabel 大小与视频分辨率不同

关于linux - 将现有的 OpenCV 应用程序包含到 Qt GUI 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37472299/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com