![]() |
OpenCV 4.12.0
开源计算机视觉
|
在图像处理中,由于您每秒要处理大量的操作,因此强制要求您的代码不仅要提供正确的解决方案,还要以最快的方式提供解决方案。因此,在本章中,您将学习
除了 OpenCV 之外,Python 还提供了一个模块 time,它有助于测量执行时间。另一个模块 profile 有助于获取代码的详细报告,例如代码中每个函数花费的时间、函数被调用的次数等。但是,如果您使用 IPython,所有这些功能都以用户友好的方式集成在一起。我们将看到一些重要的功能,有关更多详细信息,请查看附加资源部分中的链接。
cv.getTickCount 函数返回自参考事件(例如机器打开的时刻)到调用此函数时刻的时钟周期数。因此,如果您在函数执行前后调用它,您将获得执行函数所用的时钟周期数。
cv.getTickFrequency 函数返回时钟周期的频率,即每秒的时钟周期数。因此,要查找以秒为单位的执行时间,您可以执行以下操作
我们将用以下示例演示。以下示例应用中值滤波,内核大小为 5 到 49 的奇数。(不要担心结果会是什么样子 - 这不是我们的目标)
许多 OpenCV 函数都使用 SSE2、AVX 等进行了优化。 它还包含未优化的代码。 因此,如果我们的系统支持这些功能,我们应该利用它们(几乎所有现代处理器都支持它们)。 默认情况下,编译时启用它。 因此,如果启用了 OpenCV,则运行优化的代码,否则运行未优化的代码。 您可以使用 cv.useOptimized() 检查是否已启用/禁用,并使用 cv.setUseOptimized() 来启用/禁用它。 让我们看一个简单的例子。
如您所见,优化的中值滤波比未优化的版本快 2 倍。 如果您检查其源代码,您会发现中值滤波是 SIMD 优化的。 因此,您可以使用它在代码顶部启用优化(请记住,默认情况下已启用)。
有时您可能需要比较两个类似操作的性能。 IPython 为您提供了一个神奇的命令 timeit 来执行此操作。 它多次运行代码以获得更准确的结果。 再次,它适用于测量单行代码。
例如,您知道以下哪个加法运算更好,x = 5; y = x**2, x = 5; y = x*x, x = np.uint8([5]); y = x*x, 或 y = np.square(x)? 我们将在 IPython shell 中使用 timeit 找出答案。
您可以看到,x = 5 ; y = x*x 最快,并且比 Numpy 快大约 20 倍。 如果您也考虑数组创建,它可能会达到 100 倍的速度。 酷,对吧? (Numpy 开发人员正在解决此问题)
我们将尝试另一个例子。 这次,我们将比较同一图像的 cv.countNonZero() 和 np.count_nonzero() 的性能。
参见,OpenCV 函数比 Numpy 函数快近 25 倍。
还有其他几个魔术命令可以测量性能、分析、行分析、内存测量等。它们都有很好的文档记录。 因此,这里只提供指向这些文档的链接。 建议有兴趣的读者尝试一下。
有几种技术和编码方法可以最大限度地利用 Python 和 Numpy 的性能。 这里只记录了相关的,并给出了重要来源的链接。 这里要注意的主要事情是,首先尝试以简单的方式实现算法。 一旦它工作,分析它,找到瓶颈,并优化它们。
如果在完成所有这些操作后,您的代码仍然很慢,或者如果不可避免地需要使用大型循环,请使用 Cython 等其他库来使其更快。