zoukankan      html  css  js  c++  java
  • 【python-opencv】性能衡量和提升技术

    在图像处理中,由于每秒要处理大量操作,因此必须使代码不仅提供正确的解决方案,而且还必须以最快的方式提供。因此,在本章中,你将学习

    • 衡量代码的性能。
    • 一些提高代码性能的技巧。
    • 你将看到以下功能:cv.getTickCountcv.getTickFrequency等。

    除了OpenCV,Python还提供了一个模块time,这有助于衡量执行时间。另一个模块profile有助于获取有关代码的详细报告,例如代码中每个函数花费了多少时间,调用了函数的次数等。但是,如果你使用的是IPython,则所有这些功能都集成在用户友好的界面中方式。我们将看到一些重要的信息,有关更多详细信息,请查看“ 其他资源”部分中的链接。

    1、使用opencv衡量性能

    cv.getTickCount函数返回从参考事件(如打开机器的那一刻)到调用此函数那一刻之间的时钟周期数。因此,如果在函数执行之前和之后调用它,则会获得用于执行函数的时钟周期数。

    cv.getTickFrequency函数返回时钟周期的频率或每秒的时钟周期数。因此,要找到执行时间(以秒为单位),你可以执行以下操作:

    e1 = cv.getTickCount()
    # 你的执行代码
    e2 = cv.getTickCount()
    time = (e2 - e1)/ cv.getTickFrequency()

    我们将通过以下示例进行演示。下面的示例应用中位数过滤,其内核的奇数范围为5到49。(不必担心结果会是什么样,这不是我们的目标):

    img1 = cv.imread('messi5.jpg')
    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 )
    # 我得到的结果是0.521107655秒

    注意 你可以使用时间模块执行相同的操作。代替cv.getTickCount,使用time.time()函数。然后取两次相差。

    2、opencv的默认优化

    许多 OpenCV 函数都是使用 SSE2、 AVX 等进行优化的。 它还包含未优化的代码。因此,如果我们的系统支持这些特性,我们就应该利用它们(几乎所有现代的处理器都支持它们)。在编译时默认启用它。因此,如果启用了 OpenCV,它将运行优化的代码,否则它将运行未优化的代码。你可以使用 cvUseoptimized 检查是否启用 / 禁用和 cvSetuseoptimized 以启用 / 禁用它。让我们看一个简单的例子。

    #检查是否启用了优化

    # 检查是否启用了优化
    In [5]: cv.useOptimized()
    Out[5]: True
    In [6]: %timeit res = cv.medianBlur(img,49)
    10 loops, best of 3: 34.9 ms per loop
    # 关闭它
    In [7]: cv.setUseOptimized(False)
    In [8]: cv.useOptimized()
    Out[8]: False
    In [9]: %timeit res = cv.medianBlur(img,49)
    10 loops, best of 3: 64.1 ms per loop

    看,优化的中值滤波比未优化的版本快2倍。如果你检查其来源,你可以看到中值滤波是 SIMD 优化。因此,你可以使用它在代码顶部启用优化(请记住,它是默认启用的)

    3、Ipython中衡量性能

    有时你可能需要比较两个类似操作的性能。IPython为你提供了一个神奇的命令计时器来执行此操作。它会多次运行代码以获得更准确的结果。同样,它们适用于测量单行代码。

    例如,你知道以下哪个加法运算更好,x = 5; y = x**2, x = 5; y = x*x, x = np.uint8([5]); y = x*xy = np.square(x)?我们将在IPython shell中使用timeit得到答案。

    In [10]: x = 5
    
    In [11]: %测时 y=x**2
    10000000 loops, best of 3: 73 ns per loop
    
    In [12]: %测时 y=x*x
    10000000 loops, best of 3: 58.3 ns per loop
    
    In [15]: z = np.uint8([5])
    
    In [17]: %测时 y=z*z
    1000000 loops, best of 3: 1.25 us per loop
    
    In [19]: %测时 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.countNonZeronp.count_nonzero对于同一张图片的性能。

    In [35]: %测时 z = cv.countNonZero(img) 
    100000 loops, best of 3: 15.8 us per loop
    In [36]: %测时 z = np.count_nonzero(img) 
    1000 loops, best of 3: 370 us per loop

    看,OpenCV 函数比 Numpy 函数快近25倍。

    注意 通常,OpenCV函数比Numpy函数要快。因此,对于相同的操作,首选OpenCV功能。但是,可能会有例外,尤其是当Numpy处理视图而不是副本时。

    4、性能优化技术

    有几种技术和编码方法可以充分利用 Python 和 Numpy 的最大性能。这里只注明相关信息,并提供重要信息来源的链接。这里要注意的主要事情是,首先尝试以一种简单的方式实现算法。一旦它运行起来,分析它,找到瓶颈并优化它们。

    1. 尽量避免在Python中使用循环,尤其是双/三重循环等。它们本来就很慢。
    2. 由于Numpy和OpenCV已针对向量运算进行了优化,因此将算法/代码向量化到最大程度。
    3. 利用缓存一致性。
    4. 除非需要,否则切勿创建数组的副本。尝试改用视图。数组复制是一项昂贵的操作。

    即使执行了所有这些操作后,如果你的代码仍然很慢,或者不可避免地需要使用大循环,请使用Cython等其他库来使其更快。

    其他资源:

    1. Python优化技术:http://wiki.python.org/moin/PythonSpeed/PerformanceTips
    2. Scipy讲义- 高级Numpy:http://scipy-lectures.github.io/advanced/advanced_numpy/index.html#advanced-numpy
    3. IPython中的时序和性能分析:http://pynash.org/2013/03/06/timing-and-profiling/

    摘自:http://woshicver.com/FourthSection/3_3_%E6%80%A7%E8%83%BD%E8%A1%A1%E9%87%8F%E5%92%8C%E6%8F%90%E5%8D%87%E6%8A%80%E6%9C%AF/

  • 相关阅读:
    HDU 2089 不要62
    HDU 5038 Grade(分级)
    FZU 2105 Digits Count(位数计算)
    FZU 2218 Simple String Problem(简单字符串问题)
    FZU 2221 RunningMan(跑男)
    FZU 2216 The Longest Straight(最长直道)
    FZU 2212 Super Mobile Charger(超级充电宝)
    FZU 2219 StarCraft(星际争霸)
    FZU 2213 Common Tangents(公切线)
    FZU 2215 Simple Polynomial Problem(简单多项式问题)
  • 原文地址:https://www.cnblogs.com/xiximayou/p/13111773.html
Copyright © 2011-2022 走看看