【问题标题】:Cython + OpenCV and NumPyCython + OpenCV 和 NumPy
【发布时间】:2018-05-25 19:09:59
【问题描述】:

我有一个主要包含 OpenCV 和 NumPy 的程序,以及一些 SciPy。该系统需要是一个帧速率接近 30 fps 但现在只有大约 10 fps 的实时系统。使用 Cython 是否有助于加快速度?我问是因为 OpenCV 已经用 C++ 编写并且应该已经非常优化,据我所知,NumPy 也非常优化。那么使用 Cython 是否有助于缩短我的程序的处理时间?

【问题讨论】:

  • 这取决于花费的时间。 opencv/numpy 中的调用与“c”中的调用一样快。但是在python中循环,或者在python端等待相机帧很慢。搜索 SO 以分析 python 代码
  • @MartinBeckett 似乎某些 opencv 函数需要一些时间,包括捕获帧。那么在这种情况下,cython 会提供任何改进吗?
  • @downvoter 否决票背后的原因是什么?有什么需要改进的地方吗?
  • 分析您的代码,确定哪些部分花费的时间最多。然后,您可以发布一些关键部分的工作示例。没有看到一些代码,没有人能真正说出是否有可能的改进。 (我不是反对者)
  • 除非您提供代码,否则您的问题无法回答。

标签: python numpy opencv cython


【解决方案1】:

希望这对某人有所帮助

发现这篇很棒的帖子Use Cython to get more than 30X speedup on your Python code

在通过相机的视频流中使用相同的阶乘计算,每帧两帧

video_python.py

import numpy as np
import cv2
import time

def function(number):
    
    cap = cv2.VideoCapture(0)

    increment = 0

    while(True):
        # Capture frame-by-frame
        ret, frame = cap.read()

        # Our operations on the frame come here
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # Display the resulting frame
        cv2.imshow('frame',gray)

        start_time = time.time()
        y = 1
        for i in range(1, number+1):
            y *= i

        increment+=1
        if increment >2:
            # print(time.time()-start_time)
            print('Python increment ',increment)
            break
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()
    return 0

video_cython.pyx

import numpy as np
import cv2
import time

cpdef int function(int number):

    cdef bint video_true = True
    
    cap = cv2.VideoCapture(0)

    cdef int y = 1
    cdef int i

    cdef int increment = 0
    cdef int increment_times = 0

    while(video_true):
        # Capture frame-by-frame
        ret, frame = cap.read()

        # Our operations on the frame come here
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

        # Display the resulting frame
        cv2.imshow('frame',gray)

        start_time = time.time()


        for i in range(1, number+1):
            y *= i
        increment_times+=1

        if increment_times > 2:
            # print(time.time()-start_time)
            print('Cython increment ',increment_times)
            break

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()
    return 0

setup.py

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize('video_cython.pyx',compiler_directives={'language_level' : "3"}))

然后运行

python setup.py build_ext --inplace

video_test.py

import video_python
import video_cython
import time
number = 100000

start = time.time()
video_python.function(number)
end =  time.time()

py_time = end - start
print("Python time = {}".format(py_time))

start = time.time()
video_cython.function(number)
end =  time.time()

cy_time = end - start
print("Cython time = {}".format(cy_time))

print("Speedup = {}".format(py_time / cy_time))

结果:

Python 增量 3

Python 时间 = 6.602917671203613

Cython 增量 3

Cython 时间 = 0.4903101921081543

加速 = 13.466817083311046

所以在循环中做任何与 python 相关的事情都可以提高速度

【讨论】:

    【解决方案2】:

    使用Cython 不会对这个问题产生重大影响。

    要获得代码的配置文件/基准Pycharm IDE 有一个分析工具,或者您可以使用kernprof

    但是,作为测试,您可以使用以下说明将您的代码转换Cython 代码或C 代码:


    [注意]:

    这种方法适用于Python3,但也可以通过一些更改应用于Python2.7。我之前测试过。


    [更新]:

    您还可以使用PyInstallerNuitka 来测试另一种将代码转换为已编译可执行文件的方法。

    【讨论】:

    • 我同意这里的整体观点。只要您不进行逐像素操作,OpenCV 和 Numpy 应该会非常快。此外,在进行分析时,使用time.time() 您可以计算出您获得了多少 FPS。从代码末尾开始,注释掉处理操作。对我来说,运行非常简单的操作,我通常在 640x480 相机上运行 20-30 fps 在一个活泼的工作站上运行。如果我要处理更多繁重的内容,例如模板匹配或关键点/特征匹配,它会进一步下降到 10-15 fps。
    • @bfris 是的,我以前做过这个,通过信号处理我得到了差不多 10 fps...简单的帧集合通常是 30 fps 左右...
    【解决方案3】:

    这完全取决于你的程序在做什么。

    如果您的程序只是将在 C++ 中实现的大型操作串在一起,那么 cython 对您没有多大帮助。

    如果您正在编写直接作用于单个像素的代码,那么 cython 可能会有很大帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-15
      • 2012-10-04
      • 1970-01-01
      • 1970-01-01
      • 2014-11-02
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多