opencv学习笔记7:代码性能测量和效果提升

opencv学习笔记7:代码性能测量和效果提升


目标

在图像处理中,算法是不是高效很重要,接下来我们将学习:
1.测量你算法的效率
2.一些改善算法性能的小技巧
3.我们会学习使用cv2.getTickCount ,cv2.getTickFrequency等

python提供了time模块可以用来测试算法的时间花费,另一个模块profile帮助我们获取代码的细节报告,比如某个函数花费了多少时间等。

1、评测某段代码花费时间

cv2.getTickCount function returns the number of clock-cycles after a reference event (like the moment machine was switched ON) to the moment this function is called. So if you call it before and after the function execution, you get number of clock-cycles used to execute a function.

cv2.getTickFrequency function returns the frequency of clock-cycles, or the number of clock-cycles per second. So to find the time of execution in seconds, you can do following:

e1 = cv2.getTickCount()


# your code execution
e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()
We will demonstrate with following example. Following example apply median filtering with a kernel of odd size ranging from 5 to 49. (Don’t worry about what will the result look like, that is not our goal):

img1 = cv2.imread('messi5.jpg')

e1 = cv2.getTickCount()
for i in xrange(5,49,2):
    img1 = cv2.medianBlur(img1,i)
e2 = cv2.getTickCount()
t = (e2 - e1)/cv2.getTickFrequency()
print t
 #Result I got is 0.521107655 seconds

我们同样可以使用python的time模块来实现这个,使用timr.time()模块。


2、Opencv的默认优化

许多OpenCv的函数使用SSE2,AVX等进行默认优化,所以如果我们的系统支持这些,我们应当开放这些加速器(几乎所有的现代系统都支持这些操作),Opnecv在编译的时候会默认开启加速。默认使用优化后的代码,我们可以使用cv2.useOptimized()去检查是否开启优化,看个简单的例子。

#check if optimization is enabled
# 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

See, optimized median filtering is ~2x faster than unoptimized version. If you check its source, you can see median filtering is SIMD optimized. So you can use this to enable optimization at the top of your code (remember it is enabled by default).


3、使用IPython进行代码测试性能

有的时候我们需要比较两个相似操作的性能,IPython给我们一个好用的函数%timeit。这个函数多次运行代码返回一个平均运行时长,很适合测量代码的效率。
例如:
分别在python和numpy中实现
x = 5; y =x**2
x = 5; y = x*x
x = np.uint8([5]) ; y = x*x ;
比较二者的时间差异

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

我们可以看到,在python中会比在Nmupy中快约20倍。如果考虑到数组创建的耗时,实际上就快了100多倍。

Python scalar operations are faster than Numpy scalar operations. So for operations including one or two elements, Python scalar is better than Numpy arrays. Numpy takes advantage when size of array is a little bit bigger.

We will try one more example. This time, we will compare the performance of cv2.countNonZero() and np.count_nonzero() for same image.

In [35]: %timeit z = cv2.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

See, OpenCV function is nearly 25x faster than Numpy function.

Normally, OpenCV functions are faster than Numpy functions. So for same operation, OpenCV functions are preferred. But, there can be exceptions, especially when Numpy works with views instead of copies.


4、其他性能优化技术

有许多技术优化python和numpy的表现,这里只介绍一些相关的,主要的做法是找到简单的方法去实现它,找到算法的瓶颈,优化算法。
1.避免使用循环,尤其是二重三重循环,它们很慢。
2.尽可能将代码向量化,因为Numpy和Opencv都对向量进行了大量优化。
3.利用缓冲一致性
4.永远不要copy array除非必要,使用view替代,数组的copy是一个很费时的操作。
如果做完了上述所有操作,你的代码依旧很慢,或者你的代码就是需要使用大量循环,请使用一些额外的库比如Cython这样会让你的代码运行更快。


5、其他参考资料

Python Optimization Techniques
http://wiki.python.org/moin/PythonSpeed/PerformanceTips

Scipy Lecture Notes - Advanced Numpy
http://scipylectures.github.io/advanced/advanced_numpy/index.html#advanced-numpy

Timing and Profiling in IPython
http://pynash.org/2013/03/06/timing-and-profiling.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值