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.lib
和libmx.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
中提取数据。
QLineSeries
和QChart
用于显示波形图。
二、运行效果
运行Qt应用时,将启动MATLAB引擎并执行低通滤波操作,然后在Qt的窗口中显示两条波形曲线:
- 原始信号(带噪声)。
- 滤波后的信号(去噪声)。
图片如下: