1. 项目背景与核心问题定位
在计算机视觉项目的开发过程中,我们经常遇到模型输出与预期不符的情况。最近我在一个车位检测项目中就遇到了这样的挑战:部分测试图片(如1.bmp和11.bmp)的输出结果为空,而其他图片却能正常检测出车位。经过多轮排查,我们已经确认可视化链路的一致性,现在需要深入分析这些"空图"问题的根源。
关键发现:通过比对0211.txt和draw_tensor2psd_result0211.txt文件,确认下位机输出与可视化脚本的检测结果完全对应(N车位对应len=N*20),排除了可视化环节的问题。
2. 当前系统状态分析
2.1 已解决的问题
在之前的调试中,我们已经成功解决了两个关键问题:
-
inf/scale=0问题:通过添加scale保护和索引/stride修复,日志中不再出现"save to conf = inf"和"WARN: scale=0"的警告信息。
-
可视化链路一致性:下位机输出的车位数量与可视化脚本的输入数据长度严格对应,验证了数据传递过程的正确性。
2.2 现存的核心问题
目前系统仍存在两个主要问题需要解决:
-
模型在个别图片上置信度接近0:如1.bmp和11.bmp,其max_conf=0.0000,即使降低阈值也无法检出车位。
-
候选框过多导致的overflow:在7.bmp和10.bmp等图片中,当det_all final达到上限100时会出现候选截断,虽然不影响基本功能但可能影响检测质量。
3. 问题诊断方案设计
3.1 快速验证步骤
针对当前问题,建议按以下两步进行快速验证:
-
空图输入一致性比对
- 将相同的测试图片(1.bmp、11.bmp)分别在上位机/PC环境和下位机运行
- 对比两者的后处理输出max_conf值
- 可能出现的情况:
- PC有检出而下位机没有:需检查下位机前处理/量化尺度
- PC也没有检出:属于模型本身漏检(非代码问题)
-
下位机预处理图像检查
- 导出并检查1.bmp/11.bmp在下位机预处理后的图像
- 确认图像亮度、通道顺序等是否正常
- 验证图像读取是否正确(是否误读了其他图像)
3.2 诊断工具增强
为了更高效地定位问题,我在代码中添加了两个可配置的诊断功能:
3.2.1 预处理图像保存功能
c复制// 在main.c中添加
#define DEBUG_SAVE_PREPROC_BMP (0) // 开关:0关闭,1开启
// 功能实现部分
if(DEBUG_SAVE_PREPROC_BMP) {
save_preprocessed_image(pOutPlanes, "<output_file_path>/img/preproc_<原图文件名>.bmp");
}
使用说明:当需要检查预处理结果时,将宏定义改为1,程序会自动保存预处理后的BMP图像到指定目录。
3.2.2 各检测头置信度输出功能
c复制// 在mult_yolov5_post_copy.c中添加
#define DEBUG_PRINT_TOPK_CONF (1) // 开关:0关闭,1开启
#define TOPK_CONF_NUM (5) // 设置输出的top-k值
// 输出示例
for(int i=0; i<num_heads; i++) {
printf("det_head[%d] topk_conf: %.4f %.4f %.4f %.4f %.4f\n",
i, conf1, conf2, conf3, conf4, conf5);
}
这个功能可以直接显示每个检测头的前5个最高置信度值,帮助我们快速判断是模型输出问题还是后处理阈值设置问题。
4. 实操验证流程
4.1 初始验证配置建议
- 保持
DEBUG_PRINT_TOPK_CONF=1,开启各检测头的置信度输出 - 暂时设置
DEBUG_SAVE_PREPROC_BMP=0,避免生成大量图像文件 - 运行完整测试集,重点关注空图的置信度输出
4.2 深入排查步骤
当发现某张图片输出异常时:
- 设置
DEBUG_SAVE_PREPROC_BMP=1,仅针对问题图片重新运行 - 检查预处理后的图像是否正常:
- 图像内容是否正确(是否误读了其他文件)
- 色彩空间和亮度是否合理
- 图像尺寸是否符合模型输入要求
- 结合置信度输出分析:
- 如果所有检测头的top-k置信度都很低(接近0),可能是模型本身的问题
- 如果有部分检测头输出较高置信度但最终结果为空,可能是后处理参数问题
4.3 常见问题排查表
| 现象 | 可能原因 | 验证方法 | 解决方案 |
|---|---|---|---|
| 所有图片都无输出 | 模型未正确加载 | 检查模型加载日志 | 重新部署模型文件 |
| 特定图片无输出 | 1. 图像读取错误 2. 预处理异常 3. 模型漏检 |
1. 检查预处理图像 2. 对比PC端结果 |
1. 修复图像读取逻辑 2. 调整预处理参数 3. 增强模型训练 |
| 输出不稳定(时有时无) | 量化误差累积 | 对比浮点模型结果 | 调整量化参数 |
| 候选框被截断(overflow) | 候选框数量超过限制 | 检查final=100的日志 | 提高上限值或优化NMS参数 |
5. 经验总结与优化建议
在实际开发中,我总结了以下几点经验:
-
分阶段验证:先确认数据链路一致性,再排查具体模块问题,可以避免走弯路。我们首先验证了可视化链路的正确性,这为后续分析奠定了基础。
-
增量式调试:通过添加可控的诊断开关,可以灵活地获取所需信息而不影响系统正常运行。特别是对于嵌入式设备,应避免不必要的日志输出。
-
对比分析法:将下位机结果与PC端结果对比,可以快速定位问题是出在前处理、模型还是后处理环节。
-
模型健壮性检查:对于持续漏检的图片,建议:
- 检查这些图片是否在训练集中有足够多的类似样本
- 考虑数据增强策略,提高模型泛化能力
- 在无法重新训练模型的情况下,可以尝试调整输入图像的对比度、亮度等参数
-
性能与精度的平衡:对于overflow问题,需要在检测质量和系统资源之间找到平衡点。可以考虑:
- 优化NMS(非极大值抑制)参数,减少冗余候选框
- 分级处理策略,对高置信度候选优先处理
- 在资源允许的情况下适当提高上限值