OpenCV 4.11.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 等附加库来提高速度。