Qt6通过 MATLAB Engine API for C++ 方式来调用MATLAB中的函数

MATLAB提供了一个C++ API,称为MATLAB Engine API。通过这个API,Qt可以直接与MATLAB进行交互。

步骤

  • 在MATLAB安装目录中找到 engine 的头文件和库文件。
  • 在Qt项目中包含头文件(如 engine.h)并链接相关库。
  • 使用 matlab::engine 命名空间下的功能启动MATLAB引擎并执行MATLAB代码。

优点

  • 支持双向通信(从Qt传递数据到MATLAB,或者从MATLAB获取结果)。
  • 可以调用MATLAB函数并获取结果。

缺点

  • 需要MATLAB安装在运行环境中。
  • 配置复杂。

下面是简单的例子测试,在本博主电脑上测试成功。

一、工具准备:

Qt6

Qt6安装目录:

 


matlab

  

1.1 matlab环境

  • MATLAB 安装路径在系统的环境变量中,通常 matlabroot 变量是指向MATLAB安装路径。
  • matlabroot/extern/include 目录中会包含 engine.h 头文件。
  • matlabroot/bin 目录中会包含MATLAB的C++库(如 libeng.liblibmx.lib),这些库是用来编译和链接MATLAB引擎的。

在matlab中的命令行窗口输入 matlabroot,就可以看到安装路径:

matlab安装目录:

 

1.2 配置Qt6项目

1.2.1 设置Qt项目文件(.pro

在你的Qt项目中,编辑 .pro 文件,添加MATLAB引擎所需要的库和头文件路径。

INCLUDEPATH += "D:/MATLAB/R2024a/extern/include"
LIBS += -L"D:/MATLAB/R2024a/bin/win64" -leng -lmx 

1.2.2 设置源代码

你需要在Qt项目中包含MATLAB的头文件,并使用MATLAB提供的引擎接口与MATLAB进行交互。以下是一个基本示例。

这个示例实现了MATLAB的低通滤波功能,将有噪声的数据进行滤波,然后在Qt中显示去噪声前后的波形图,主要分为以下几步:

MATLAB部分:低通滤波

MATLAB提供了多种方式来实现低通滤波,常用的包括使用 lowpass 函数或使用 filter 函数。我们可以调用MATLAB中的低通滤波函数,并返回滤波前后的数据供Qt调用。

Qt部分:使用MATLAB Engine API与MATLAB交互

在Qt中,我们将MATLAB的数据通过MATLAB Engine API进行交互,将MATLAB处理的结果传递回Qt,之后在Qt UI中显示波形图。

Qt创建一个Qwidget工程,带UI界面的。

通过MATLAB引擎调用滤波函数

完整.pro文件如下:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets charts

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

INCLUDEPATH += "D:/MATLAB/R2024a/extern/include"
LIBS += -L"D:/MATLAB/R2024a/bin/win64" -leng -lmx

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

main.cpp文件如下:

#include <iostream>
#include "engine.h"
#include <QApplication>
#include <QChartView>
#include <QLineSeries>
#include <QVBoxLayout>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // 启动MATLAB引擎
    Engine *ep;
    ep = engOpen(NULL);  // 启动MATLAB引擎

    if (ep == NULL) {
        std::cerr << "无法启动MATLAB引擎!" << std::endl;
        return -1;
    }

    // 执行MATLAB代码,进行低通滤波
    engEvalString(ep, "fs = 1000; t = 0:1/fs:1; signal = sin(2*pi*50*t) +             0.5*randn(size(t));");
    // 设置采样频率为1000Hz,生成时间向量t,生成包含50Hz正弦信号和噪声的信号
    engEvalString(ep, "fc = 100; [b, a] = butter(6, fc/(fs/2), 'low');");
    // 设置截止频率为100Hz,设计一个6阶低通巴特沃斯滤波器
    engEvalString(ep, "filtered_signal = filter(b, a, signal);");
    // 对信号进行滤波

    // 获取MATLAB中的信号和滤波后的信号
    mxArray *original_signal = engGetVariable(ep, "signal");
    // 从MATLAB引擎中获取原始信号
    mxArray *filtered_signal = engGetVariable(ep, "filtered_signal");
    // 从MATLAB引擎中获取滤波后的信号

    // 提取信号数据到C++变量
    double *orig_signal_data = mxGetPr(original_signal);
    // 获取原始信号的数据指针
    double *filt_signal_data = mxGetPr(filtered_signal);
    // 获取滤波后信号的数据指针

    int signal_length = mxGetNumberOfElements(original_signal);
    // 获取信号的长度

    // 准备Qt UI界面显示波形
    QLineSeries *originalSeries = new QLineSeries();
    // 创建一个用于存储原始信号的QLineSeries对象
    QLineSeries *filteredSeries = new QLineSeries();
    // 创建一个用于存储滤波后信号的QLineSeries对象

    for (int i = 0; i < signal_length; ++i) {
        originalSeries->append(i / 1000.0, orig_signal_data[i]);  // 时间单位为秒
        // 将原始信号的数据添加到QLineSeries对象中,时间单位为秒
        filteredSeries->append(i / 1000.0, filt_signal_data[i]);
        // 将滤波后信号的数据添加到QLineSeries对象中,时间单位为秒
    }

    // 创建两个图表
    QChart *originalChart = new QChart();
    // 创建一个用于显示原始信号的QChart对象
    originalChart->addSeries(originalSeries);
    // 将原始信号的QLineSeries对象添加到QChart对象中
    originalChart->createDefaultAxes();
    // 创建默认的坐标轴
    originalChart->setTitle("Original Signal (With Noise)");
    // 设置图表标题

    QChart *filteredChart = new QChart();
    // 创建一个用于显示滤波后信号的QChart对象
    filteredChart->addSeries(filteredSeries);
    // 将滤波后信号的QLineSeries对象添加到QChart对象中
    filteredChart->createDefaultAxes();
    // 创建默认的坐标轴
    filteredChart->setTitle("Filtered Signal (Noise Removed)");
    // 设置图表标题

    // 创建图表视图
    QChartView *originalChartView = new QChartView(originalChart);
    // 创建一个用于显示原始信号图表的QChartView对象
    originalChartView->setRenderHint(QPainter::Antialiasing);
    // 设置渲染提示,启用抗锯齿

    QChartView *filteredChartView = new QChartView(filteredChart);// 创建一个用于显示滤波后信号图表的QChartView对象

    filteredChartView->setRenderHint(QPainter::Antialiasing);// 设置渲染提示,启用抗锯齿


    // 创建并显示窗口
    QWidget window;
    // 创建一个QWidget对象作为窗口
    QVBoxLayout *layout = new QVBoxLayout();
    // 创建一个垂直布局管理器
    layout->addWidget(originalChartView);
    // 将原始信号图表视图添加到布局中
    layout->addWidget(filteredChartView);
    // 将滤波后信号图表视图添加到布局中
    window.setLayout(layout);
    // 设置窗口的布局管理器
    window.resize(800, 600);
    // 设置窗口的大小
    window.show();
    // 显示窗口

    // 关闭MATLAB引擎
    engClose(ep);

    return a.exec();
}

在项目中启用 Qt Charts 模块: 如果你已经安装了 Qt Charts 模块,需要在你的 Qt 项目的 .pro 文件中启用它。打开 .pro 文件并添加以下行:

QT += charts

包含头文件: 在Qt代码中正确包含Qt Charts的头文件。确保你在文件顶部添加了:

#include <QtCharts>

配置Qt Creator: 在Qt Creator中,确保项目的配置使用了正确的Qt版本,并且 Qt Charts 模块已经启用。

函数说明如下: 

signal = sin(2*pi*50*t) + 0.5*randn(size(t));:生成带有噪声的信号。randn 函数生成随机噪声。

butter(6, fc/(fs/2), 'low'):设计一个6阶的低通Butterworth滤波器,截止频率为 fc

filter(b, a, signal):使用设计的滤波器对信号进行滤波。

engOpen(NULL):启动MATLAB引擎。

engEvalString:执行MATLAB代码,包括生成信号、设计滤波器和执行滤波操作。

engGetVariable:获取MATLAB中的变量(滤波前后的信号)。

mxGetPr:从MATLAB返回的 mxArray 中提取数据。

QLineSeriesQChart 用于显示波形图。

二、运行效果

运行Qt应用时,将启动MATLAB引擎并执行低通滤波操作,然后在Qt的窗口中显示两条波形曲线:

  • 原始信号(带噪声)
  • 滤波后的信号(去噪声)

图片如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值