OpenCV算法开发注意事项

为项目找到最佳的OpenCV算法

任何计算机视觉问题都可以用不同的方法来解决。每种方法都有其优点和缺点,以及成功的相对衡量标定,这取决于数据、资源或目标

并非所有的OpenCV实现都能轻松地应用于给定的问题。例如,虽然OpenCV提供了一些对象识别和分类函数,但它远达不到在会议和文献中看到的最先进的计算机视觉的效果。如果能在OpenCV的核心模块找到相关函数,那将是一个好兆头,因为意味着有足够的文档、示例和健壮性。但OpenCV对于SfM、对象分类等重要主题的覆盖率依然很低。

在计算机视觉项目的实现过程中,工程师可能会考虑在原型设计阶段之后就不再使用OpenCV,因为库很大,并且会显著增加构建和部署的开销(尤其对移动应用程序而言,是一个严重问题)。
此时,OpenCV是一个很好的原型设计工具,因为它提供了广泛的功能,可以针对相同的任务在不同算法之间进行选择,例如计算二维特征,这对测试也很有用。其还支持Python语言,可简化原型开发过程。
除了原型阶段之外,许多其他因素变得更加重要,例如执行环境、代码的稳定性和可维护性、权限和许可等。此时,需要综合考量OpenCV能否满足产品的需求。

计算机视觉并不是垂直向上、递进发展的,这意味着对于一个给定问题,新的解决方案并不总是更好的,而且可能没有基于前面的工作。作为一个应用领域,计算机视觉算法关注以下几个方面
(1)计算资源:CPU、GPU、嵌入式系统、内存占用、网络连接
(2)数据:图像大小、图像数量、图像流(摄像头)数量、数据类型、顺序、照明条件、场景类型等
(3)性能要求:实时输出或其他时间限制(例如人类感知)、准确性和精度
(4)元算法:算法的简单性(参考奥卡姆剃刀定律)、实现系统和外部工具、形式化证明的可用性

由于每一种算法都是为了满足某一个考虑因素而创建的,因此,如果没有对其中的一部分或全部进行适当的测试,人们永远无法确定它是否会优于其他算法。当然,即便OpenCV确实提供了许多可用的实现,测试给定问题的所有算法是不现实的。另一方面,如果计算机视觉工程师不考虑由于他们的算法选择而使他们的实现不是最佳的可能性,他们将会是失职的。(测试不同算法的主要问题是需要书写测试代码,这是工程师额外的工作,这并非易事。为一项工作选择最佳的计算机视觉算法是一个吃力不讨好的过程,这也是许多工程师不愿意执行它的原因。)在确定最佳算法之前,测试一组不同的算法选项是非常受欢迎的做法

在很多时候,一个成功的度量标定是:对误差进行度量,误差来自人类或我们可以信任的其他算法的已知基准值与算法结果的偏差。在优化中,这被称为损失函数,我们希望最小化(或最大化)这个函数,以便找到最佳选项。另一类重要的度量不太关心输出精度(例如误差),而更多地关心运行时间、内存占用、容量和吞吐量等。
在计算机视觉问题中常用的度量包括
(1)重建、配准、特征匹配任务:平均绝对误差(MAE)、均方误差(MSE)、均方根误差(RMSE)、平方距离之和(SSD);
(2)对象分类、识别任务:准确度、精确度、召回率、F1值、假正类率(FPR)
(3)分割、目标检测任务:检测评价函数(IoU)
(4)特征检测:重复性、精确率、召回率
如果测试的数据足够多,我们可以统计推断过程和假设检验,例如t检验或方差分析(ANOVA),以确定条件之间的微小差异是否具有统计学意义,或者仅是个例,无法区分。

避免OpenCV中的常见陷阱

任何希望为其工作选择性能最佳算法的工程师都应该拥有查询特定算法的工具,可以查看何时添加该算法以及其来源(例如研究论文)。这意味着新的算法并不一定会更好,因为一些基本算法和旧算法仍然表现出色,并且在大多数情况下,需要根据各种指标来进行取舍。

对严谨的计算机视觉工程师来说,深入检查OpenCV代码应该是一项例行工作。

OpenCV具有丰富的特性,拥有多个选项意味着几乎不可能找到精确的最佳性能解决方案,因为许多部分是可互换的,测试所有可能的选项是力所不及的。输入数据使这个问题的复杂性呈指数级增加,输入数据中更多未知的噪声将使我们的算法选择更加不稳定。
换句话说,使用OpenCV或任何其他计算机视觉库仍然是经验和艺术的问题。关于解决方案的一条或另一条路线是否成功的先验直觉是计算机视觉工程师在多年经验的基础上建立的,这在很大程度上没有捷径

在任何工程领域,最常见的问题都是所假设的与真实情况不符。对于一个工程师来说,如果可以对某些东西进行测量,那么就应该测量它,也可以采用近似测量,确定其上下界,或者测量不同的但高度相关的现象。
最好的决策是基于硬数据和可见性的知情决策;然而,这通常不由工程师控制。有些项目需要快速从头构建,这迫使工程师在没有太多数据或直觉的情况下从零开始快速构建解决方案。在这种情况下,下面的建议可以避免很多麻烦
(1)不对可选择的算法进行比较:对现状一无所知时,就决定选择算法将非常不明智。
解决方案:Python作为高级语言,在交换算法方面具有更大的灵活性。可使用Python构建算法原型,在建立好数据管道之后,查看如何交换某些算法或它们的参数,并测试对最终结果的影响,即超参数调优
(2)不对本地解决方案或算法做单元测试:单元测试是一种出色的工具,可确保功能不会因意外输入、无效数据或边缘情况(例如空图像)而中断,并且具有很好的退化支持。
解决方案:为代码中任何有意义的函数建立单元测试,并确保涵盖了重要部分。
(3)不检查数据范围:计算机视觉编程中的一个常见问题是假设数据的范围。由于内存块可以保存任何值,所以不能保证这些假设在任何情况下都成立。
解决方案:检查输入数据范围,并确保它是你所期望的。如果范围不在可接受的范围内,则可能抛出out_of_range异常。也可使用CV_ASSERT检查范围,这将在失败时触发cv::error异常。
(4)数据类型、通道、转换和舍入错误:OpenCV中的cv::Mat数据结构中最棘手的问题之一是它的变量类型上没有携带数据类型信息。接收函数无法知道数组内包含哪些数据,可能导致OpenCV函数出现运行时异常。
解决方案:首选cv::Mat_<>类型(例如cv::Mat_)而不是cv::Mat类型,以便携带数据类型,并建立明确的变量命名约定(例如cv::Mat image_8uc1),然后进行数据测试,以确保你得到的类型就是期望的类型,或创建一个“规范化”方案,将任何意外的输入类型转换为希望在函数中使用的类型。
(5)颜色空间引起的问题——RGB、感知(HSV、Lab)与技术(YUV)对比:OpenCV不会跟踪cv::Mat中的颜色空间信息。同时必须记住:在常用的HSV颜色空间中,H(色调)实际上的度量是[0,360]度,但被压缩到[0,180]以适应uchar类型。
解决方案:始终了解待处理数据的颜色空间。当没有可用的颜色空间信息时,可以依赖启发式方法或测试下输入。通常,你应该警惕只有2个通道的图像,因为它们很可能是位压缩的颜色空间。
(6)精度、速度、资源(CPU、内存)之间的权衡和优化*:在大多数情况下,得到一些特性就会失去另一些特性。不注意这些权衡,或过分关注它们,可能都会成为一个问题。工程师常见的陷阱是优化问题:优化不足或过度优化、过早优化、不必要的优化。而在实际中导致效率低下的元凶通常只有一个,即代码或算法。
解决方案:在使用算法之前或使用算法时了解算法。如果你选择了一种算法,请进行测试,或者至少查看OpenCV的文档页面,确保你了解它的复杂性(运行时间和资源)。

[查找计算机视觉数据集的一个好用资源是:
(https://riemenschneider.hayko.at/vision/dataset/)]

[OpenCV通过HAL(硬件加速层)从而超越了Intel x86架构(例如ARM、NEON),该架构后来合并到核心模块中。]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值