qml+opencv(一)

本文探讨了如何在QML中利用OpenCV进行人脸识别的尝试。通过继承QQuickItem并实现updatePaintNode函数,将opencv图像转换为QSGTexture,结合QSGSimpleTextureNode在QML中进行渲染。作者还封装了轮廓扫描算法,并展示了初步的视觉效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

突然想起opencv,一直想做人脸识别,可是理论基础太水,只能慢慢来,去年学习了一会,然后公司让我去搞app和网络,就一直搁着,现在学习qml,突然想能不能在qml里面使用opencv,所以就有了这篇文章。

QQuickItem和QObject

在QML中,可视化的基础组件是Item,不可视化的就是QtObject,它们对应C++中的QQuickItem和QObject类,扩展QML组件一个继续基于QML中的Item扩张,还有就是继承QQuickItem,我们想把opencv加到QML中,那么只有继承QQuickItem了。
怎么使用,那还要看QML新的渲染机制,Qt5的QML渲染基于OpenGL,其场景的渲染在单独的线程进行,我们需要需要QQuickItem返回能够描述场景的对象,就是QSGNode。实现QQuick的updatePaintNode函数就OK了,我们在updatePaintNode,描述怎么渲染。

类的关系

OpenCVcapture继承QOjbect,其是图像捕获的基类,OpenCVcamera是OpenCVcapture子类,完成从摄像头捕获数据。OpenCVaction类封装了opencv图像算法操作。OpenCVshowFrame继承QQuickItem,实现可视化。

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml/qqml.h>
#include "opencvcamera.h"
### 如何在 QML 中集成与配置 OpenCV 要在 QML 中集成和配置 OpenCV,通常需要通过 C++ 后端实现 OpenCV 的功能,并将其暴露给 QML 层面进行调用。以下是具体方法: #### 1. 安装 OpenCV 库 确保已经在 Linux 或其他操作系统上成功安装了 OpenCV 库[^3]。如果尚未完成此步骤,则需按照官方文档或相关教程(如 Ubuntu 下的编译指南[^2])完成 OpenCV 的安装。 #### 2. Qt 项目设置 为了使 OpenCV 能够正常工作于 Qt 项目中,在 `.pro` 文件中添加必要的路径和链接库: ```plaintext INCLUDEPATH += /path/to/opencv/include LIBS += -L/path/to/opencv/lib \ -lopencv_core \ -lopencv_imgproc \ -lopencv_highgui \ -lopencv_videoio ``` 上述路径应替换为实际环境中 OpenCV 的头文件目录以及动态库所在位置[^1]。 #### 3. 创建自定义 QObject 类桥接 QMLOpenCV 由于 QML 不支持直接访问 OpenCV 功能,因此可以创建个继承 `QObject` 的类作为桥梁。该类封装所需的功能并将它们注册到 QML 上下文中以便使用。 ##### 示例代码 (C++) ```cpp #include <QObject> #include <QString> #include <QImage> // 导入 opencv 头文件 #include <opencv2/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> class ImageProcessor : public QObject { Q_OBJECT public: explicit ImageProcessor(QObject *parent = nullptr) : QObject(parent) {} // 将 cv::Mat 转换为 QImage 并返回其数据 URL 表示形式 QString processAndConvert(const QString &filePath); signals: private slots: }; QString ImageProcessor::processAndConvert(const QString &filePath){ cv::Mat img = cv::imread(filePath.toStdString()); if(img.empty()){ return ""; } // Convert from BGR to RGB since QImage uses the latter format. cv::cvtColor(img, img, cv::COLOR_BGR2RGB); QImage qImg((uchar*)img.data, img.cols,img.rows, static_cast<int>(img.step), QImage::Format_RGB888); QByteArray byteArray; QBuffer buffer(&byteArray); buffer.open(QIODevice::WriteOnly); qImg.save(&buffer,"PNG"); // writes image into byte array in PNG format return QStringLiteral("data:image/png;base64,") + QString::fromLatin1(byteArray.toBase64().constData()); } ``` #### 4. 注册类型至 QML 为了让上面定义好的 `ImageProcessor` 可用于 QML ,还需要把它注册成上下文属性或者作为个新的可实例化对象类型提供出来。 ##### 方法 A: 设置为 Context Property ```cpp int main(int argc, char **argv){ QApplication app(argc, argv); QQmlApplicationEngine engine; ImageProcessor processor; engine.rootContext()->setContextProperty(QStringLiteral("imageProcessor"),&processor); const QStringqmlFile=QStringLiteral("qrc:/main.qml"); engine.load(qmlFile); returnapp.exec(); } ``` ##### 方法 B: 使用 plugin 方式加载 另种更灵活的方式是把此类打包成插件供多个工程共享复用,这里不再赘述细节。 #### 5. 在 QML 中调用处理函数 旦完成了以上准备工作之后就可以轻松地从 QML 页面上调用这些接口啦! ##### 主界面 .qml 文件片段 ```javascript import QtQuick 2.15 import QtQuick.Controls 2.15 ApplicationWindow{ visible:true width:640;height:480 Button{ text:"Load and Process" onClicked:{ var result=imageProcessor.processAndConvert("/absolute/path/image.jpg") console.log(result) myImageView.source=result } } ImageView{id:myImageView;} } ``` 这样就实现了基于 QML 对图像资源应用 OpenCV 进行预览显示等功能扩展^。 ---
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值