Mir*_*age 2 c++ qt camera android qml
我想在桌面和Android上使用QWidgets/C++在我的Qt机器人项目上显示和获取Camera的框架.相机在只有QML的程序中工作,但我的实际项目需要在C++中使用QWidgets.
我尝试了各种方式:
我找到了问题的答案(目标是从相机获取帧并在Android和Windows上的QWidget上显示)
首先在QML中:获取相机并过滤:
Item {
signal submitFrame(var img)//used to send QImage to C++ after filter process
Camera {
id: camera
}
MyFilter {
id: filter
onFinished: submitFrame(result)
}
VideoOutput {
source: camera
filters: [ filter ]
}
}
Run Code Online (Sandbox Code Playgroud)
QAbstractVideoFilter子类:
class MyFilter : public QAbstractVideoFilter
{
Q_OBJECT
public:
MyFilter();
QVideoFilterRunnable *createFilterRunnable();
signals:
void finished(const QVariant& result); //send QImage got to QML
public slots:
};
Run Code Online (Sandbox Code Playgroud)
QVideoFilterRunnable子类:
class MyFilterRunnable : public QVideoFilterRunnable
{
public:
MyFilterRunnable(MyFilter *filter);
~MyFilterRunnable();
QVideoFrame run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags) Q_DECL_OVERRIDE;
private:
MyFilter *m_filter;
};
Run Code Online (Sandbox Code Playgroud)
处理框架(将QVideoframe转换为QImage)
QVideoFrame run(QVideoFrame *input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags) Q_DECL_OVERRIDE;
//On Android
if(frame->handleType() == QAbstractVideoBuffer::GLTextureHandle){
/* ...
Need treatment with OpenGL or other to "convert" frame to QImage.
see here : http://code.qt.io/cgit/qt/qtmultimedia.git/tree/examples/multimedia/video/qmlvideofilter_opencl in file rgbframehelper.h
... */
emit m_filter->finished(QVariant (imgToDisplay));// send QImage got to QML
}
//On Windows
else{
//easy convert VideoFrame to QImage
QImage::Format format = VideoFrame::imageFormatFromPixelFormat(frame->pixelFormat());
if (fmt != QImage::Format_Invalid){
QImage img=QImage(frame->bits(), frame->width(), frame->height(), format);
QImage imgToDisplay = img.convertToFormat(QImage::Format_RGB888);
emit m_filter->finished(QVariant(imgToDisplay));// send QImage got to QML
}
}
Run Code Online (Sandbox Code Playgroud)
现在在C++上,MainWindow:
qmlRegisterType<MyFilter>("my.uri", 1, 0, "MyFilter");
//load QML
QQuickView *view=new QQuickView();
view->setSource(QUrl("qrc:///main.qml"));
view->show();
//connect to get QImage as QVariant from QML to this C++ class
QObject *topLevel =view->rootObject();
QObject::connect(topLevel, SIGNAL(submitFrame(const QVariant &)),this, SLOT(handleFrame(const QVariant &)));
Run Code Online (Sandbox Code Playgroud)
和显示槽:
void MainWindow::handleFrame(const QVariant &in)
{
//cast Qvariant =>QImage
QImage image = in.value<QImage>();
// QImage to QPixmap for display
ui->label->setPixmap(QPixmap::fromImage(image));
ui->label->resize(image.size());
ui->label->update();
}
Run Code Online (Sandbox Code Playgroud)
总结一下:QML相机"发送"帧到c ++过滤器.过滤将帧转换为QImage并将这些QImage作为QVariant发送到QML.从C++显示类,使用connect获取QVariant并转换为QImage以在QWidget上显示.
这当然不是最好的方式(Android转换框架到QImage太慢了,可能用QML和C++进行大量扩展)但它足以满足我的项目(我得到~15 fps).
如果有人有更好的想法来改进这个过程,请说出来!
| 归档时间: |
|
| 查看次数: |
3851 次 |
| 最近记录: |