【C++/Qt桌面开发实战03】Qt 6 + OpenCV + ONNX Runtime:风电齿轮五分类诊断平台完整实现
【C++/Qt桌面开发实战03】Qt 6 + OpenCV + ONNX Runtime:风电齿轮五分类诊断平台完整实现
前言
前两篇分别记录了 Qt 6.11.1 + MSVC 开发环境搭建,以及 Qt Widgets 中的文件选择、信号与槽和时频图显示。本篇继续把项目向“可以实际演示和交付”的方向推进:将训练好的 CNN-Mamba 五分类模型部署到 Qt 桌面端,完成单图诊断、批量诊断、置信度分析、混淆矩阵、CSV/HTML 报告和界面可用性优化。
项目名称为 GearVision AI——风电机组齿轮智能故障诊断平台。当前版本为 Release 1.2.1,主要面向已经生成的 MSSTFrFT 时频图。由于目前还没有接入真实单片机或采集卡,本文重点记录软件推理链路和真实样本验证,不把结果描述成硬件在线监测。
项目仓库:
https://github.com/jdai10590-afk/CppQt-Desktop-Development
一、项目目标与技术栈
本次开发希望解决三个问题:
- 让 PyTorch 训练得到的模型可以在纯 C++ 桌面程序中运行;
- 不只显示一个分类标签,还要给出概率、统计特征和不确定性提示;
- 支持批量评估和报告导出,方便继续核对不同工况下的泛化能力。
| 模块 | 采用技术 |
|---|---|
| 桌面界面 | Qt 6.11.1 Widgets |
| 编程语言 | C++17 |
| 图像处理 | OpenCV |
| 推理引擎 | ONNX Runtime 1.27 |
| 分类模型 | CNN-Mamba |
| 输入数据 | MSSTFrFT 时频图 |
| 输出类别 | broken、healthy、missing_tooth、root_crack、wear |
对应的中文类别分别为:断齿、正常、缺齿、齿根裂纹和磨损。
二、整体推理流程
平台的核心流程如下:
时频图 → OpenCV 解码与预处理 → CHW 浮点张量 → ONNX Runtime 推理 → Softmax 概率 → 五分类结果 → 历史记录与报告
为了避免训练端和部署端不一致,类别顺序必须在导出模型、验证脚本和 Qt 程序中完全一致:
const std::vector<std::string> kClassNames = {
"broken",
"healthy",
"missing_tooth",
"root_crack",
"wear"
};
如果这里的顺序错了一位,即使模型输出数值完全正确,界面显示的标签也会错误。因此部署模型时,类别映射和输入预处理与模型文件同等重要。
三、OpenCV 图像预处理与 ONNX Runtime 推理
单张图像进入模型前,需要依次完成:
- 使用 OpenCV 读取 PNG、JPG 或 BMP;
- 将 BGR 转为 RGB;
- 缩放到模型要求的 224×224;
- 转换为 float,并按训练阶段的方式归一化;
- 将 HWC 排列转换为 CHW;
- 构造 ONNX Runtime 输入张量;
- 运行模型并对输出执行 Softmax。
核心逻辑可以概括为:
cv::Mat image = cv::imread(imagePath);
cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
cv::resize(image, image, cv::Size(224, 224));
image.convertTo(image, CV_32F, 1.0 / 255.0);
std::vector<float> inputTensorValues(3 * 224 * 224);
// 省略 HWC -> CHW 的逐通道拷贝代码
auto outputTensors = session.Run(
Ort::RunOptions{nullptr},
inputNames.data(),
&inputTensor,
1,
outputNames.data(),
1
);
实际项目中最容易出错的地方并不是 Session.Run,而是颜色通道、归一化方式、输入尺寸和类别顺序。我的做法是保留 Python 端基准结果,再使用同一批图片逐张核对 C++ 输出。
四、平台已经实现的主要功能
1. 单图诊断
点击“导入单张时频图”,或直接把图片拖入窗口,即可完成时频图预览、五分类推理、完整概率显示、推理耗时统计,以及历史记录和运行日志写入。
2. 图像统计特征
除了模型结果,程序还计算了 8 个灰度统计特征:均值、标准差、方差、均方根、峰值、偏度、峭度和峰值因子。
这些指标不能代替深度学习分类,但可以帮助快速检查图像亮度、能量分布以及异常峰值,也便于发现错误图片或预处理异常。
3. 时频能量曲线
平台按图像横向采样统计平均能量,并绘制时频能量曲线。它可以辅助观察主要能量带的位置和变化趋势,使诊断界面不只是“输出一个标签”。
4. 批量诊断
批量模式会递归扫描文件夹中的图片,并显示当前文件名、完成数量、总数量、进度百分比、平均推理耗时、异常样本数量,同时支持中途取消。
程序只在父目录名与五个类别之一匹配时,才把目录名当作真实标签。这样可以避免普通文件夹名被误认为类别,导致准确率统计失真。
5. 结果导出
当前支持导出 CSV 明细与 HTML 诊断报告。报告可包含样本路径、预测类别、真实标签、五类概率、置信度、推理耗时和复核标记,便于后续归档或撰写实验记录。
五、加入不确定性评估,避免只看最高概率
仅显示 Softmax 最大值并不够。例如第一名和第二名很接近时,即使最高概率超过 50%,模型也可能处于犹豫状态。
因此程序同时计算 Top-1 置信度、Top-2 置信度、概率差值 Margin 和归一化信息熵 Entropy。
当前复核阈值如下:
constexpr float kReviewConfidenceThreshold = 0.70f;
constexpr float kReviewMarginThreshold = 0.20f;
constexpr float kReviewEntropyThreshold = 0.65f;
满足以下任一条件,样本就会被标记为“建议复核”:
- 最高置信度低于 70%;
- 第一名与第二名的概率差小于 20%;
- 归一化熵高于 0.65。
同时,界面上的“健康分数”定义为:
Health Score = P(healthy) × 100
这里需要特别说明:它只是模型对“正常”类别的概率展示,不是剩余寿命 RUL,也不是经过物理标定的健康指标。如果未来要做寿命预测,需要连续退化数据、时间标签和单独的回归或生存分析模型。
六、批量评估:从“能运行”升级到“能核对”
对带标签的目录批量诊断后,程序会统计:
- Accuracy;
- Macro-F1;
- 每一类的 Precision、Recall、F1;
- 5×5 混淆矩阵;
- 低置信度和建议复核样本。
这些指标比单独看准确率更有意义。例如某一类样本数量少,即使整体准确率较高,也可能出现该类别召回率很低的问题;混淆矩阵则能直接显示模型最容易混淆的类别组合。
在当前数据中,MSSTFrFT / speed20 可作为回归核对基线。对 speed25 等不同转速工况,如果准确率明显下降,首先应该排查域偏移、训练数据覆盖和预处理一致性,而不能直接把问题归结为 Qt 或 ONNX Runtime 推理错误。
七、本轮重点修复的界面问题
1. 批量进度百分比显示不全
原来的进度条高度不足,百分比文字会被裁切。修复后增加了进度条高度,并让百分比在进度条内部居中显示。无论 9%、44% 还是 100%,都可以完整看到。
2. 长路径导致横向溢出
批量诊断时,完整文件路径很长,容易把界面撑宽。现在主要区域只显示文件名,完整路径放入工具提示中;主窗口关闭不必要的横向滚动,减少界面抖动。
3. 左侧运行概览卡片文字被遮挡
窗口高度有限时,统计卡片会被压缩,标题和值互相覆盖。Release 1.2.1 将卡片设置为稳定高度,调整了侧边栏间距和日志区域最小高度,保证“已诊断、准确率、异常样本、平均耗时”在常见分辨率下都能正常显示。
4. 日志持续增长影响长时间运行
运行日志现在限制为最近 800 行。这样既能保留足够的排错信息,也可以避免长时间批量诊断后界面越来越卡。
八、真实样本验证与结果说明
为了验证完整部署链路,我从五个类别目录中分别选取一张真实时频图,自动执行单图推理烟雾测试。结果为:
- 5 张真实样本全部完成推理;
- 五个类别映射均核对正确;
- 测试进程退出码为 0;
- 模型加载、图像预处理、ONNX 推理和结果显示链路正常。
这里的 5/5 只代表五类各一张样本的部署烟雾测试通过,不能替代完整测试集上的 Accuracy、Macro-F1 和混淆矩阵。模型的最终性能仍应以独立测试集和跨工况验证为准。
Windows 发布包已经完成依赖整理,共包含 61 个文件,并执行 SHA 校验,便于后续复制到其他电脑进行演示。
九、软件的实际使用步骤
- 启动 GearVisionAI.exe;
- 确认左侧状态显示“ONNX 模型已就绪”;
- 单图测试时点击“导入单张时频图”,或直接拖入图片;
- 批量测试时选择包含类别子目录的数据集根目录;
- 观察概率分布、复核标记、统计指标和混淆矩阵;
- 点击导出按钮保存 CSV 或 HTML 报告。
推荐的数据目录结构如下:
dataset/
├─ broken/
├─ healthy/
├─ missing_tooth/
├─ root_crack/
└─ wear/
十、下一步计划
- 增加跨转速、跨工况训练与域泛化实验;
- 支持原始振动信号 CSV/TXT 导入,显示时域波形和频谱;
- 增加误判样本筛选、按置信度排序和一键打开所在目录;
- 在有真实连续退化标签后,再研究健康趋势和 RUL;
- 后续接入单片机、采集卡或传感器,实现真正的在线数据链路;
- 补充安装说明、演示视频和可复现实验记录。
总结
这次开发完成了从“训练模型”到“可交互桌面诊断平台”的关键一步。Qt 负责稳定的工程界面,OpenCV 负责图像处理,ONNX Runtime 负责跨平台推理,批量评估和不确定性分析则让结果更容易核对。
对工业故障诊断项目来说,软件能打开只是起点。真正重要的是:训练与部署预处理一致、类别映射正确、指标可解释、低置信度结果能够被发现,并且对烟雾测试和完整评估保持清晰边界。
后续我会继续记录跨工况验证、原始振动信号接入和硬件联调过程。
更多推荐
所有评论(0)