OPenCV - QML图像处理(1):在QML中显示OPenCV图片

写在前面 

以前写过一个OPenCV图像处理的工具,界面是这样的:

有兴趣的朋友用用:https://pan.baidu.com/s/16_DYfTnvp8cj7aqzXAlMGQ 提取码:5s9e

这个是用QWidget写的,打算用QML重写一遍,界面用QML,内部逻辑用C++。

不定时更新。

正文

首先要有一个显示图片的控件。根据 用 C++ 编写 QML 扩展 可知,这可以是一个继承QQuickPaintedItem 的自定义类,在自定义类中实现绘制图片然后将它注册到QML中。这个类尽量只显示图片和做一些交互操作,既然如此,那么需要再定义一个工具类,OpenCV图片处理的操作都在工具类中进行。

显示图片的控件如下:

#ifndef SHOWMATITEM_H
#define SHOWMATITEM_H

#include <QQuickPaintedItem>
#include <QPixmap>
#include <opencv2/core/core.hpp>

class ShowMatItem : public QQuickPaintedItem
{
    Q_OBJECT
    QML_ELEMENT

public:
    ShowMatItem(QQuickItem *parent = 0);
    void paint(QPainter *painter)override;
    Q_INVOKABLE void setSrcFile(const QString & filePath);

private:
    cv::Mat mat;
    QString srcFilePath;
};

#endif // SHOWMATITEM_H
#include "showmatitem.h"
#include <QPainter>
#include <QPixmap>
#include <QDebug>
#include "util.h"

ShowMatItem::ShowMatItem(QQuickItem *parent)
    :QQuickPaintedItem(parent)
{
}

void ShowMatItem::paint(QPainter *painter)
{
    painter->setRenderHints(QPainter::Antialiasing, true);
    auto rect = boundingRect().toRect();
    painter->drawPixmap(rect,util::matToPixmap(rect.size(),mat));
}

void ShowMatItem::setSrcFile(const QString & filePath)
{
    QString temp = filePath;
    srcFilePath = temp.remove("file:///").replace("/","\\");
    util::readImage(temp,mat);
    update();
}

工具类如下:

#ifndef UTIL_H
#define UTIL_H

#include <QPixmap>
#include <opencv2/core/core.hpp>

class util
{
public:
    static QPixmap matToPixmap(const QSize & size,const cv::Mat & mat);//Mat转QPixmap
    static void readImage(const QString & filePath,cv::Mat & mat);//打开一张图片

private:
    util();
};

#endif // UTIL_H
#include "util.h"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <QTextCodec>

util::util()
{
}

QPixmap util::matToPixmap(const QSize & size, const cv::Mat & mat)
{
    if(mat.empty())
        return QPixmap();

    auto img = QImage((const unsigned char*)(mat.data),
                      mat.cols,
                      mat.rows,
                      mat.cols * mat.channels(),
                      QImage::Format_RGB888);
    return QPixmap::fromImage(img.scaled(size));
}

void util::readImage(const QString & filePath,cv::Mat & mat)
{
    mat = cv::imread(QTextCodec::codecForName("gb18030")->fromUnicode(filePath).data());
    cv::cvtColor(mat,mat,cv::COLOR_BGR2RGB);
}

定义完成,然后是注册,注册以后定义的控件就能在QML中使用了:

    qmlRegisterType<ShowMatItem>("com.qmlcompany.cppComponents", 1, 0, "ShowMatItem");

main.qml 代码:

import QtQuick 2.14
import QtQuick.Controls
import com.qmlcompany.cppComponents 1.0
import Qt.labs.platform 1.1 as Labs //名称冲突了要用as,注意Labs要大写开头

ApplicationWindow
{
    visible: true
    title: qsTr("OpenCV图像处理助手")
    color:"#FFFFFF"
    width: 1000; height: 600
    menuBar: MenuBar
    {
        Menu
        {
            title: qsTr("文件")
            MenuItem
            {
                 text: qsTr("打开文件")
                 onTriggered:
                 {
                     fileDialog.open()
                 }
                 Labs.FileDialog
                 {
                     id: fileDialog
                     title: qsTr("打开图片或者txt文件")
                     nameFilters: ["image files (*.png *.jpg *.jpeg *.bmp)"]
                     acceptLabel: qsTr("确定")
                     rejectLabel: qsTr("取消")
                     fileMode: Labs.FileDialog.OpenFile
                     onAccepted:
                     {
                         var filePath = fileDialog.files[0]
                         srcImage.setSrcFile(filePath)
                     }
                 }
            }

            MenuSeparator {}
            MenuItem
            {
                 text: qsTr("退出")
                 onTriggered: Qt.quit()
            }
        }
    }

    ShowMatItem
    {
        id:srcImage
        anchors.fill: parent
    }
}

目前代码就这些,比较简单。

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
要在Qt6使用QML显示OpenCV获取的摄像头,可以按照以下步骤进行: 1. 首先需要在Qt项目包含OpenCV头文件和库文件。 2. 创建一个QML窗口,并在其添加一个QML Camera元素。 3. 使用OpenCV获取摄像头图像,并将其转换为QImage格式。 4. 将QImage格式的图像传递给QML Camera元素,并在QML窗口显示。 以下是一个简单的示例代码: main.cpp: ``` #include <QGuiApplication> #include <QQmlApplicationEngine> #include <opencv2/opencv.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); // OpenCV capture object cv::VideoCapture cap(0); if (!cap.isOpened()) { qWarning() << "Failed to open camera"; return -1; } QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); // Get QML camera object QObject *qmlObj = engine.rootObjects().first()->findChild<QObject*>("camera"); // Loop to capture and display frames while (true) { cv::Mat frame; cap >> frame; if (frame.empty()) { qWarning() << "Failed to capture frame"; break; } // Convert OpenCV Mat to QImage QImage qImg(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888); qImg = qImg.rgbSwapped(); // Set image on QML camera object QMetaObject::invokeMethod(qmlObj, "setImage", Qt::QueuedConnection, Q_ARG(QVariant, QVariant::fromValue(qImg))); } cap.release(); return app.exec(); } ``` main.qml: ``` import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import QtMultimedia 5.15 ApplicationWindow { visible: true width: 640 height: 480 title: "OpenCV Camera" GridLayout { columns: 1 rows: 1 anchors.fill: parent Camera { id: camera objectName: "camera" captureMode: Camera.CaptureVideo imageProcessing.whiteBalanceMode: CameraImageProcessing.WhiteBalanceAuto imageProcessing.colorFilter: CameraImageProcessing.ColorFilterNone imageProcessing.contrast: 1 imageProcessing.saturation: 1 imageProcessing.sharpness: 0 imageProcessing.manualWhiteBalance: Qt.rgba(1, 1, 1, 1) imageProcessing.brightness: 1 imageProcessing.iso: CameraImageProcessing.ISOAuto imageProcessing.exposureCompensation: 0 imageProcessing.exposureMode: CameraImageProcessing.ExposureAuto objectName: "cameraView" anchors.fill: parent } } } ``` 在这个示例,我们使用OpenCV从摄像头获取图像,并将其转换为QImage格式。然后,我们将QImage格式的图像传递给QML Camera元素,并在QML窗口显示。注意,在QML我们使用了Camera元素,它可以显示来自摄像头的实时视频流。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值