OpenCV 4.10.0
开源计算机视觉
|
在图像处理中,由于每秒需要处理大量操作,因此务必要确保您的代码不仅提供了正确的解决方案,还以最快的速度提供了该解决方案。因此,在本章中,您将学习
除了 OpenCV 之外,Python 还提供了一个模块time,它有助于测量执行时间。另一个模块profile有助于获取代码的详细报告,例如代码中每个函数花费了多少时间,该函数被调用的次数等。但是,如果您正在使用 IPython,所有这些功能都以一种用户友好的方式集成在一起。我们将重点介绍其中的一些重要功能,有关更多详细信息,请查看其他资源部分中的链接。
cv.getTickCount 函数返回从某个参考事件(例如机器打开时的时刻)到调用此函数的时刻的时钟周期数。因此,如果您在函数执行前和执行后调用它,您将获得用来执行函数的时钟周期数。
cv.getTickFrequency 函数返回时钟周期数的频率,或每秒的时钟周期数。因此,若要找出以秒为单位的执行时间,您可以执行以下操作:
我们通过以下示例进行演示。以下示例应用奇数大小介于 5 到 49 之间的核进行中值滤波。(不要担心结果是什么样子 - 那不是我们的目标)
许多 OpenCV 函数使用 SSE2、AVX 等优化。它们也包含一些未优化的代码。因此,如果我们的系统支持这些特性,我们应充分利用它们(几乎所有现代处理器都支持)。在编译过程中默认启用这些特性。因此,如果已启用,OpenCV 将运行已优化的代码;否则,将运行未优化的代码。你可以使用 cv.useOptimized() 检查其是否已启用/禁用,使用 cv.setUseOptimized() 启用/禁用。我们来看一个简单的示例。
如你所见,优化后的中值滤波比未优化版本快 2x。如果你查看它的源代码,会发现中值滤波经过 SIMD 优化。因此,你可以将其用于在代码顶部启用优化(记住,它在默认情况下是启用的)。
有时你可能需要比较两个类似操作的性能。IPython 提供了一个 magic 命令 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 倍。
还有其他几个 magic 命令用于测量性能、分析、行分析、内存测量,等等。它们都有详细的文档。因此,此处仅提供那些文档的链接。建议有兴趣的读者尝试一下。
有几种技术和编码方法可以利用 Python 和 Numpy 的最大性能。此处仅说明了相关方法,并给出了重要资料的链接。此处需要说明的主要事项是,首先尝试以简单的方式实现算法。一旦它开始工作,对其进行概要分析,找出瓶颈,并对其进行优化。
如果在执行所有这些操作后,您的代码仍然很慢,或者不可避免地使用大型循环,请使用 Cython 等其他库使其更快。