AI-on-the-edge-device 模拟表盘 ROI 图片留存参数 ROIImagesRetention 完全解析
2026/9/16 18:25:31 网站建设 项目流程

AI-on-the-edge-device 模拟表盘 ROI 图片留存参数 ROIImagesRetention 完全解析

【免费下载链接】AI-on-the-edge-deviceEasy to use device for connecting "old" measuring units (water, power, gas, ...) to the digital world项目地址: https://gitcode.com/GitHub_Trending/ai/AI-on-the-edge-device

导读ROIImagesRetention是 AI-on-the-edge-device 水表/电表图像识别固件中控制模拟指针表盘(Analog)ROI 分离图片保留时长的核心参数。它直接决定 SD 卡上调试图片的占用空间与可追溯深度。读完本文你将掌握:该参数在config.ini中的配置位置与取值规则、固件底层按天删除旧图片的完整实现原理、0(永久保留)与默认值的实际差异,以及如何在 Web 配置界面和旧版本配置迁移中正确处理它。

一、参数速览

ROIImagesRetention属于[Analog]配置段,官方参数文档定义如下(见 ROIImagesRetention.md):

属性
参数名ROIImagesRetention
默认值3
单位天(Days)
含义保留分离出的 Analog ROI 图片的天数,0= 永久保留

简单来说:设备每次拍照识别时,会从整帧画面中按 ROI(Region of Interest,感兴趣区域)坐标裁切出每个模拟表盘小窗的独立图片并保存到 SD 卡,用于后续排查识别错误、追溯历史读数。ROIImagesRetention决定这些裁切图片在 SD 卡上保留多久,超过保留期的历史图片会被固件自动清理。

注意:同一个参数在数字表盘(Digits)段同样存在,二者相互独立,见 Digits/ROIImagesRetention.md。

二、配置文件中的位置与用法

固件的全部运行参数存放在 SD 卡的config.ini中。在仓库自带的 config.ini 模板里,[Analog]段默认以注释形式给出该参数:

[Analog] Model = /config/ana-cont_1500_s2_q.tflite CNNGoodThreshold = 0.5 ;ROIImagesLocation = /log/analog ;ROIImagesRetention = 3 main.ana1 432 230 92 92 false main.ana2 379 332 92 92 false main.ana3 283 374 92 92 false main.ana4 155 328 92 92 false

关键点:

  • 行首分号;表示注释:默认模板中该行被注释,固件会使用内置兜底值;取消注释并填写数值即可启用自定义保留期。
  • 必须与ROIImagesLocation配合ROIImagesLocation指定 Analog ROI 图片的存储目录(默认示例/log/analog),只有设置了位置并启用图片记录后,ROIImagesRetention才有实际作用。二者在解析阶段是联动的(详见下文源码分析)。
  • 取值规则:输入必须为非负整数(单位为天)。0表示永久保留、永不自动删除;任何正数表示保留最近 N 天内的图片。

在仓库的演示配置 sd-card/demo/config.ini 中可以看到同样的注释写法,说明这是面向所有部署场景的统一约定。

三、源码级实现原理

1. 参数解析与联动关系

Analog(以及 Digits)段的参数解析统一在ClassFlowCNNGeneral::ReadParameter中完成,见 ClassFlowCNNGeneral.cpp:

if ((toUpper(splitted[0]) == "ROIIMAGESLOCATION") && (splitted.size() > 1)) { this->imagesLocation = "/sdcard" + splitted[1]; this->isLogImage = true; } if ((toUpper(splitted[0]) == "ROIIMAGESRETENTION") && (splitted.size() > 1)) { if (isStringNumeric(splitted[1])) { this->imagesRetention = std::stoi(splitted[1]); } }

可以从中确认三点实现事实:

  • 位置是开关:只有解析到ROIImagesLocationisLogImage才会被置为true,图片记录功能才算真正启用;否则后续所有日志/清理逻辑都会直接短路返回(ClassFlowImage.cppCreateLogFolderLogImageRemoveOldLogs三处均以if (!isLogImage) return;开头)。
  • 数值校验:解析前先调用isStringNumeric校验,只有纯数字才通过std::stoi写入,非法值会被静默忽略。
  • 存储类型imagesRetention在 ClassFlowCNNGeneral.h 中声明为unsigned short,天然不支持负数——这正对应"0= 永久保留"的语义设计。

2. 图片的目录结构与命名

启用图片记录后,每次识别流程会在 ClassFlowTakeImage.cpp 与ClassFlowCNNGeneral::doFlow(见 ClassFlowCNNGeneral.cpp)中依次执行:建目录 → 保存原图 → 裁切 ROI → 清理过期图片。

目录按日期/小时两级分层(见 ClassFlowImage.cpp):

string logPath = imagesLocation + "/" + time.LOGFILE_TIME_FORMAT_DATE_EXTR + "/" + time.LOGFILE_TIME_FORMAT_HOUR_EXTR;

例如默认位置/log/analog下会生成/log/analog/20260915/14/这样的子目录,每小时的裁切图集中存放,便于按时间浏览。文件命名规则见 LogImage 实现:模拟表盘的结果是浮点数,文件名以%.1f_前缀记录读数(如3.4_main.ana1_20260915_1430.jpg),负值/无效值使用N.N_前缀,10.0 会归一化为0.0_

3. 过期清理逻辑:RemoveOldLogs

这正是ROIImagesRetention发挥作用的核心函数,完整实现见 ClassFlowImage.cpp。其流程为:

if (imagesRetention == 0) { return; // 0 = 永久保留,直接跳过清理 } time(&rawtime); rawtime = addDays(rawtime, -1 * imagesRetention + 1); // 计算保留阈值日期 strftime(cmpfilename, 30, LOGFILE_TIME_FORMAT, timeinfo); DIR *dir = opendir(imagesLocation.c_str()); while ((entry = readdir(dir)) != NULL) { // 对 imagesLocation 下的每个子目录(即日期目录): // 若目录名长度与日期格式一致,且字典序小于阈值日期,则整目录删除 if ((strlen(entry->d_name) == folderName.length()) && (strcmp(entry->d_name, folderName.c_str()) < 0)) { removeFolder(folderPath.c_str(), logTag); } }

几个值得注意的实现细节:

  • 0是特判imagesRetention == 0时函数直接返回,不做任何扫描与删除,SD 卡上的 ROI 图片会无限累积——这也是"永久保留"的代码级保证。
  • 阈值按天取整:阈值日期 = 当前时间减去(retention - 1)天。例如保留 3 天时,第 4 天及更早的日期目录会被删除,从而在任意时刻最多留存最近 3 个自然日的数据,语义与"保留 N 天"完全吻合。
  • 按日期目录粒度删除:清理以"天"为最小粒度,不精确到小时级文件,避免频繁的小文件操作,降低对 SD 卡写入寿命的影响。
  • 清理时机:在每次识别流程结束时触发(Analog/Digits 的doFlow末尾以及拍照流程的RemoveOldLogs()调用),因此无需定时任务,天然与采样周期同步。

4. 与原始大图的区别

注意区分:ROIImagesRetention管理的是ROI 分离小图(Analog 表盘裁切图),而整帧原图的保留时长由[TakeImage]段的RawImagesRetention独立控制(见 ClassFlowTakeImage.cpp)。二者的解析逻辑几乎一致,但存储位置与用途不同:原图体积大、主要用于整体画面回放;ROI 小图体积小、专门用于逐表盘诊断。实际部署时可分别设置不同的保留策略。

四、通过 Web 界面配置

固件内置的 Web 配置界面同样暴露了该参数。在 edit_config_template.html 的 Analog 段可以找到对应表单控件:

<tr class="AnalogItem"> <td> <input type="checkbox" id="Analog_ROIImagesRetention_enabled" ...>ROI Images Retention </td> <td> <input required type="number" id="Analog_ROIImagesRetention_value1" min="0" step="1" oninput="(!validity.rangeUnderflow||(value=0)) && (!validity.stepMismatch||(value=parseInt(this.value)));">Days </td> </tr>

从控件属性可以读出界面层施加的约束:

  • type="number"+min="0":只允许输入不小于 0 的数值,从源头杜绝负数。
  • step="1"+oninput中的parseInt处理:强制为整数(天),小数输入会被取整。
  • 勾选复选框启用该项后保存,readconfigparam.js会通过 ParamAddValue(param, catname, "ROIImagesRetention") 将数值写入config.ini对应段。

对于习惯直接编辑文件的用户,也可以像第二节那样手工修改config.ini后重启设备生效。

五、旧版本配置自动迁移

如果是从早期固件升级,旧配置中的参数名会自动迁移。在固件启动阶段的配置迁移逻辑 main.cpp 中:

else if (section == "[Digits]") { migrated = migrated | replaceString(configLines[i], "LogImageLocation", "ROIImagesLocation"); migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "ROIImagesRetention"); } else if (section == "[Analog]") { migrated = migrated | replaceString(configLines[i], "LogImageLocation", "ROIImagesLocation"); migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "ROIImagesRetention"); }

也就是说:旧版参数LogfileRetentionInDays(图片保留天数)会被自动改名为ROIImagesRetentionLogImageLocation会被改名为ROIImagesLocation,无需用户手工迁移。需要留意的是,[TakeImage]段的同名旧参数则会迁移为RawImagesRetention(main.cpp),三个段的旧参数指向各自新名称,升级后务必检查各段最终生效值是否符合预期。

六、取值建议与注意事项

结合参数语义与实现逻辑,给出如下实操建议:

  1. 调试期调大、稳定期调小:刚完成对焦、ROI 对齐或换模型时,建议设置7~15天甚至临时设为0永久保留,方便回溯问题样本;识别稳定后改回默认3即可。
  2. 警惕0的副作用0= 永久保留意味着图片只增不减。长期运行会持续占用 SD 卡空间、加剧闪存写入磨损,仅在明确需要长期追溯时使用,并配合定期手动备份。
  3. RawImagesRetention配合规划空间:ROI 小图单张仅几十 KB,但每小时一张、一天 24 张累加起来仍会增长。可按"原图保留更短、ROI 图保留更长"的策略分层配置,兼顾排查能力与存储寿命。
  4. 确认位置参数已启用:若图片从未生成,先检查ROIImagesLocation是否已取消注释——按源码逻辑,未设置位置时isLogImage为 false,整个图片记录与清理链路都不会执行。

七、进一步阅读

  • 参数定义原文:Analog/ROIImagesRetention.md、Digits/ROIImagesRetention.md
  • 完整配置模板:sd-card/config/config.ini、sd-card/demo/config.ini
  • 清理与保存实现:ClassFlowImage.cpp、ClassFlowCNNGeneral.cpp
  • 原图保留参数(对照参考):TakeImage/RawImagesRetention.md
  • Web 界面表单:edit_config_template.html、readconfigparam.js
  • 配置迁移逻辑:main.cpp

【免费下载链接】AI-on-the-edge-deviceEasy to use device for connecting "old" measuring units (water, power, gas, ...) to the digital world项目地址: https://gitcode.com/GitHub_Trending/ai/AI-on-the-edge-device

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询