Я хочу отобразить поток изображений с устройства захвата в Qt3D (через текстуру).
Итак, я вложил в подкласс QPaintedTextureImage
:
#include <Qt3DRender/QPaintedTextureImage>
#include <QPainter>
#include <QImage>
#include <QPaintDevice>
#include <opencv2/opencv.hpp>
class OpenCVCaptureImage : public Qt3DRender::QPaintedTextureImage
{
public:
explicit OpenCVCaptureImage(Qt3DCore::QNode *parent = nullptr);
void paint(QPainter *painter) override;
private:
cv::VideoCapture cap_;
};
OpenCVCaptureImage::OpenCVCaptureImage(Qt3DCore::QNode *parent)
: Qt3DRender::QPaintedTextureImage(parent),
cap_(0)
{
}
void OpenCVCaptureImage::paint(QPainter *painter)
{
cv::Mat frame;
cap_ >> frame;
QImage im(static_cast<uchar *>(frame.data), frame.cols, frame.rows, int(frame.step), QImage::Format_RGB888);
if(im.isNull()) return;
setSize(im.size());
//int w = painter->device()->width();
//int h = painter->device()->height();
painter->drawImage(0, 0, im);
}
Согласно документация :
A QPaintedTextureImage должна быть разделена на подклассы, а виртуальная функция paint () должна быть реализована.Каждый раз, когда update () вызывается для QPaintedTextureImage, вызывается функция paint () и полученное изображение загружается.
Поэтому я добавляю Timer
к своей сценедерево, и в слоте onTriggered
я вызываю capImage.update()
, но что-то идет не так во время выполнения:
2019-01-31 22: 48: 54.865282 + 0100 Qt3DOpenCV [50001:4569220] qrc: /MyScene.qml: 57: TypeError: Свойство 'update' объекта Qt3DRender :: QPaintedTextureImage (0x106ef6bf0) не является функцией
main.cpp:
#include <QGuiApplication>
#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include "opencvcaptureimage.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
qmlRegisterType<OpenCVCaptureImage>("OpenCVCaptureImage", 1, 0, "OpenCVCaptureImage");
QGuiApplication app(argc, argv);
Qt3DExtras::Quick::Qt3DQuickWindow view;
view.setSource(QUrl("qrc:/MyScene.qml"));
view.show();
return app.exec();
}
MyScene.qml:
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
import OpenCVCaptureImage 1.0
import QtQml 2.12
Entity {
id: sceneRoot
RenderSettings {
id: renderSettings
activeFrameGraph: ForwardRenderer {
clearColor: Qt.rgba(0, 0.5, 1, 1)
camera: Camera {
id: objectsCamera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: 16/9
nearPlane : 0.1
farPlane : 1000.0
position: Qt.vector3d( 0.0, 0.0, -40.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
}
}
}
InputSettings {
id: inputSettings
}
components: [renderSettings, inputSettings]
PlaneMesh {
id: planeMesh
width: 2
height: 2
}
TextureMaterial {
id: planeMaterial
texture: Texture2D {
id: planeTexture
textureImages: [
OpenCVCaptureImage {
id: capImage
}
]
}
}
Timer {
interval: 500
running: true
repeat: true
onTriggered: capImage.update()
}
Transform {
id: planeTransform
rotationX: 90
}
Entity {
id: planeEntity
components: [ planeMesh, planeMaterial, planeTransform ]
}
}
РЕДАКТИРОВАТЬ: Я также попытался поместить таймер в конструктор C ++:
OpenCVCaptureImage::OpenCVCaptureImage(Qt3DCore::QNode *parent)
: Qt3DRender::QPaintedTextureImage(parent),
cap_(0)
{
QTimer::singleShot(2500, [=] {
auto t = new QTimer(this);
connect(t, &QTimer::timeout, [=] {
this->update();
});
t->setInterval(200);
t->start();
});
}
в этом случае программа падаетQPainter::drawImage
, и эта ошибка выводится на консоль:
2019-02-01 11: 15: 45.754907 + 0100 Qt3DOpenCV [55788: 4839633] QPaintDevice: Невозможно уничтожить устройство рисования, котороерисуется