目录
前言
跟着官网学习opencv-python才是基础入门的最佳选择,下文是官网的学习记录及扩展!
目标
在图像处理中,由于您每秒要处理大量操作,因此您的代码不仅必须提供正确的解决方案,而且还必须以最快的方式提供解决方案。因此,我们需要:
*衡量代码的性能。
*提高代码性能的一些提示。
*涉及函数:cv.getTickCount,cv.getTickFrequency等。
函数详解
1.使用OpenCV检测程序效率
函数介绍:
cv.getTickCount
函数返回从参考点到这个函数被执行的时钟数。因此,如果在函数执行之前和之后调用它,则会得到用于执行函数的时钟周期数。
cv.getTickFrequency
函数返回时钟周期的频率或每秒时钟周期数。因此,要以秒为单位查找执行时间,您可以执行以下操作:
代码演示:
对奇数大小的内核应用中值滤波,范围从 5 到 49:
import cv2 as cv
img1 =cv.imread('lena.png')
e1 = cv.getTickCount()
for i in range(5,49,2):
img1 = cv.medianBlur(img1,i)
e2 = cv.getTickCount()
t = (e2 - e1)/cv.getTickFrequency()
print( t ) # 1.0998926 seconds
python中time模块也可以实现,调用的函数是time.time()
2.OpenCV中的默认优化
许多OpenCV函数都是使用SSE2,AVX等进行优化的。它还包含未优化的代码。
因此,如果我们的系统支持这些功能,我们就应该利用它们(几乎所有现代处理器都支持它们)。
默认情况下,它在编译时处于启用状态。
cv2.useOptimized()来查看优化是否被开启,
cv2.setUesOptimized()来开启/禁用优化。
官方案例使用的是魔法函数%timeit
# check if optimization is enabled
In [5]: cv2.useOptimized()
Out[5]: True
In [6]: %timeit res = cv2.medianBlur(img,49)
10 loops, best of 3: 34.9 ms per loop
# Disable it
In [7]: cv2.setUseOptimized(False)
In [8]: cv2.useOptimized()
Out[8]: False
In [9]: %timeit res = cv2.medianBlur(img,49)
10 loops, best of 3: 64.1 ms per loop
上述可知,优化的中值滤波比未优化的版本快 2 倍。
3.在IPython中检测程序效率
有时您可能需要比较两个类似操作的性能。IPython给你一个神奇的命令时间来执行这个。它会多次运行代码以获得更准确的结果。再次,它适用于测量单行代码。
例如,你知道下面同一个数学运算用哪种方式的代码会执的更快吗?
x = 5; y = x∗∗2
x = 5; y = x∗x
x = np.uint8([5]); y = x∗x
y = np.square(x)
我们可以在 IPython 的 Shell 中找到答案。
import cv2
import numpy as np
In [10]: x = 5
In [11]: %timeit y=x**2
10000000 loops, best of 3: 73 ns per loop
In [12]: %timeit y=x*x
10000000 loops, best of 3: 58.3 ns per loop
In [15]: z = np.uint8([5])
In [17]: %timeit y=z*z
1000000 loops, best of 3: 1.25 us per loop
In [19]: %timeit y=np.square(z)
1000000 loops, best of 3: 1.16 us per loop
可以看出,(x = 5; y = x∗x)是最快的且比Numpy快20倍;如果考虑到数组构建的话,还可以快到100倍。
注意:Python 标量操作比 Numpy 标量操作更快。因此,对于包含一两个元素的操作,Python 标量比 Numpy 数组更好。当数组的大小稍大一点时,Numpy 具有优势。
我们将再尝试一个例子。这一次,我们将比较性能cv.countNonZero() 和 np.count_nonzero() 用于同一图像。
In [35]: %timeit z = cv.countNonZero(img)
100000 loops, best of 3: 15.8 us per loop
In [36]: %timeit z = np.count_nonzero(img)
1000 loops, best of 3: 370 us per loop
可以看出,OpenCV 函数比 Numpy 函数快近 25 倍。
通常,OpenCV函数比Numpy函数更快。因此,对于相同的操作,OpenCV函数是首选。但是,可能会有例外,尤其是当 Numpy 使用views而不是copies时。
4.效率优化技术
有些技术和编码方法可以利用Python和Numpy的最大性能。
这里要注意的主要事情是,首先尝试以简单的方式实现算法。
一旦它开始工作,分析它,找到瓶颈,并优化它们。
尽可能避免在 Python 中使用循环,尤其是双/三循环等。它们本质上很慢。
最大限度地矢量化算法/代码,因为 Numpy 和 OpenCV 针对矢量操作进行了优化。
利用缓存一致性。
除非必要,否则切勿复制数组。尝试改用视图。阵列复制是一项成本高昂的操作。
如果您的代码在执行所有这些操作后仍然很慢,或者如果不可避免地使用大循环,请使用其他库(如 Cython)来使其更快。
参考
OpenCV: OpenCV-Python Tutorials
Python Optimization Techniques
Scipy Lecture Notes - Advanced Numpy
Timing and Profiling in IPython
学习、进步、坚持。。。内容不间断更新中。。。