如何在Android和带有Qt的桌面上使用摄像头

如何在Android和带有Qt的桌面上使用摄像头,android,c++,qt,camera,qml,Android,C++,Qt,Camera,Qml,我想在使用QWidgets/C++的Qt robot项目中,在桌面和Android上显示并获取相机的框架。 相机只在QML中工作,但我的实际项目需要在C++中使用QWIDGET。 我尝试了各种方法: QQuickView带有显示QML摄像头的容器,Android无法使用 我试过这个: 但我不明白 我也看到了这个:/ 但它不适用于Android 我找到了我的问题的答案(目标是从相机中获取帧并在Android和Windows上的QWidget上显示) QML中的第一个:获取相机和过滤器: Item

我想在使用QWidgets/C++的Qt robot项目中,在桌面和Android上显示并获取相机的框架。 相机只在QML中工作,但我的实际项目需要在C++中使用QWIDGET。 我尝试了各种方法:

  • QQuickView带有显示QML摄像头的容器,Android无法使用
  • 我试过这个: 但我不明白
  • 我也看到了这个:/ 但它不适用于Android

  • 我找到了我的问题的答案(目标是从相机中获取帧并在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 ]
        }
    }
    
    QAbstractVideoFilter子类:

    class MyFilter : public QAbstractVideoFilter
    {
        Q_OBJECT
    public:
        MyFilter();
    
        QVideoFilterRunnable *createFilterRunnable();
    
    signals:
        void finished(const QVariant& result); //send QImage got to QML
    
    public slots:
    };
    
    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;
    };
    
    QVideoFilterRunnable子类:

    class MyFilter : public QAbstractVideoFilter
    {
        Q_OBJECT
    public:
        MyFilter();
    
        QVideoFilterRunnable *createFilterRunnable();
    
    signals:
        void finished(const QVariant& result); //send QImage got to QML
    
    public slots:
    };
    
    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;
    };
    
    处理帧(将QVideoframe转换为QImage)

    现在C++,主窗口:< /P>

    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 &)));
    
    qmlRegisterType(“my.uri”,1,0,“MyFilter”);
    //加载QML
    QQuickView*视图=新的QQuickView();
    查看->设置源(QUrl(“qrc:///main.qml"));
    查看->显示();
    //连接以将QImage作为qFALLL从QML获取到C++类
    QObject*topLevel=view->rootObject();
    QObject::connect(顶层,信号(submitFrame(const QVariant&)),this,插槽(handleFrame(const QVariant&));
    
    和显示槽:

    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();
    }
    
    void主窗口::扶手框架(const QVariant&in)
    {
    //铸造Qvariant=>QImage
    QImage image=in.value();
    //QImage到QPixmap进行显示
    ui->label->setPixmap(QPixmap::fromImage(image));
    ui->label->resize(image.size());
    用户界面->标签->更新();
    }
    

    总结:QML相机将“帧”发送到C++过滤器。过滤器将帧转换为QImage,并将这些QImage作为QVariant发送到QML。从C++显示类中,得到qConnect与Connect和CAST到QVIDEN,以显示在QWIDGET上。 这当然不是最好的方法(Android将frame转换为QImage太慢了,可能需要使用QML和C++),但这对于我的项目来说已经足够了(我得到了~15 fps)


    如果有人有更好的想法,请分享。

    Qt widgets相机示例:它在Android上不起作用(相机不会启动和崩溃),我担心,但这在小部件上是不可能的,请参阅。剩下的问题太模糊了,无法回答。更具体地说,我怎样才能在Android上从相机中获取画面?根据我发布的链接,这似乎是可能的。QCamera不起作用,Android也不起作用,但也许我可以从QML中获取框架,并在“C++”中导入,转换并处理为QImage以显示在QWidgetAs@BaCaRoZzo上。他说,使用小部件无法做到这一点。我会尝试类似于您所说的方法—将简单的QML场景嵌入到您的小部件项目中。