自上次发表文章至今已逾一个月,期间因突发的紧急任务导致原定计划有所延误,进而影响了部分内容的更新进度。鉴于此,现亟需重新规划并恢复更新工作。
本文将直接进入主题,探讨在实际操作中遇到的具体问题及解决方案,特别是采用二分查找算法优化阈值设定以改善模型性能的方法。鉴于基础知识已在先前文献中充分论述,此处不再赘述。
采用二分查找算法优化阈值设定的原因在于,尽管经过图像分割处理后,模型对于直线的识别率已达到约90%,但在将Python代码转换为C++代码并成功部署ONNX模型进行预测后,若从头开始重构可能会涉及大量的重复劳动。因此,考虑在不改变现有架构的前提下,通过调整阈值来提高直线检测的准确性,旨在确保在不同应用场景下均能获得尽可能多的正确检测结果。由于项目保密性要求,具体代码细节无法在此公开,但将通过其他实例详尽解释二分查找算法的应用过程。
在实践中,通过调整阈值确实可以在一定程度上提升直线检测的准确性,然而该策略的有效性亦受限于图像的具体环境条件,如背景过暗可能导致即便调整阈值也难以准确识别目标线。为此,在实施过程中,首先尝试利用二分查找算法针对线段长度设定阈值,但初步实验结果显示效果并不理想。随后,进一步优化了检测流程:在编写的相关函数中,通过动态调整阈值`mid`来探索最优解,确保检测出的线段数目既非零也不超过100个。此过程涉及设定阈值搜索区间`left`与`right`,并通过迭代计算`mid`值来逐步缩小搜索范围,直至找到最适宜的阈值。此外,针对前100条线段的优先级处理,则依据数据特性及模型训练阶段预设的参数`top_k`进行相应调整。
二分法的基本原理
二分法(Binary Search)是一种高效的搜索算法,通常用于在有序数组中查找特定元素。然而,它的应用不仅限于此,还可以用于优化问题,如在一定范围内寻找最优解。在你的代码中,二分法用于自动调整检测线条的阈值,以找到一个合适的阈值,使得检测到的线段数量在一个合理的范围内。
-
初始化搜索范围:
定义一个初始的搜索范围[left, right]
。在这个范围内,我们假设最优解一定存在。 -
计算中间值:
计算当前搜索范围的中间值mid
,即mid = (left + right) / 2
。 -
评估中间值:
- 使用中间值
mid
作为当前的阈值,执行一次检测操作,得到结果。 - 根据结果的性质(例如,检测到的线段数量),决定如何调整搜索范围。
- 使用中间值
-
调整搜索范围:
- 如果当前结果满足条件(例如,检测到的线段数量在合理范围内),则记录当前阈值为最优解。
- 如果当前结果不满足条件,根据结果的性质调整搜索范围:
- 如果检测到的线段数量过多,说明阈值太低,需要提高阈值,即
left = mid
。 - 如果检测到的线段数量过少,说明阈值太高,需要降低阈值,即
right = mid
。
- 如果检测到的线段数量过多,说明阈值太低,需要提高阈值,即
-
终止条件:
当搜索范围足够小(例如,right-left< ε
,其中ε
是一个小的正数),或者找到满足条件的阈值时,终止搜索。
代码中的应用
在你的代码中,二分法用于自动调整检测线条的阈值,具体步骤如下:
-
初始化搜索范围:
float left = 0.0f; float right = 0.60f;
-
计算中间值:
float mid = (left + right) / 2;
-
评估中间值:
liness.clear(); liness = pred_lines_onnx(img, net, { 1, 3, 960, 960 }, mid);
-
调整搜索范围:
if (liness.size() <= 100 && liness.size() > 0) { best = mid; break; } if (liness.size() <= 0) { right = mid; } else { left = mid; }
-
终止条件:
if (right - left < 0.01) { best = left; break; }
优点
高效性:每次迭代将搜索范围缩小一半,因此在对数时间内找到最优解。
鲁棒性:适用于各种优化问题,特别是当目标函数单调或近似单调时。
通过以上步骤,二分法能够在较短的时间内找到一个合适的阈值,使得检测到的线段数量在一个合理的范围内,从而提高检测的准确性和效率。