I have a program with mainly OpenCV and NumPy, with some SciPy as well. The system needs to be a real-time system with a frame rate close to 30 fps but right now only about 10 fps. Will using Cython help speed this up? I ask because OpenCV is already written in C++ and should already be quite optimized, and NumPy, as far as I understand, is also quite optimized. So will the use of Cython help improve the processing time of my program?
-
2it depends what is taking the time. The calls inside opencv/numpy are as fast as they will be in 'c'. But looping in python, or waiting for camera frames in the python side is slow. Search SO for profiling python code – Martin Beckett May 25 '18 at 19:44
-
@MartinBeckett it seems that some of the opencv functions are taking some time, including capturing frames. So in this case would cython provide any improvement? – TanMath May 25 '18 at 19:45
-
Most likely cython will provide a speedup, but if it's going to be 10% or 1000% is impossible to tell from such a distance. – user7138814 May 25 '18 at 19:52
-
1@downvoter what is the reason behind the downvote? Is there something I should improve? – TanMath May 25 '18 at 19:54
-
4Profile your code, identify which parts takes the most time. Then you can post some working example of the critical part(s). Nobody can really say if there are possible improvements without seeing some code. (I am not the downvoter) – max9111 May 25 '18 at 20:53
-
@TanMath I am not the down voter I also up vote. I update my answer. – Benyamin Jafari Jun 01 '18 at 20:33
-
1Your question is unanswerable unless you provide your code. – Mark Setchell Jun 02 '18 at 09:44
3 Answers
Hope this helps someone
Found this awesome post Use Cython to get more than 30X speedup on your Python code
Used the same factorial calculation inside video stream through the camera for two frames each
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"}))
then run
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))
result:
Python increment 3
Python time = 6.602917671203613
Cython increment 3
Cython time = 0.4903101921081543
Speedup = 13.466817083311046
So doing any kind of python related stuff inside the loop can increase speed

- 1
- 1

- 1,134
- 12
- 26
-
Looks like the only thing you are optimizing with cyhton here is that extra loop for 100000 iterations, that has nothing to do with opencv here. – Pawel Jun 17 '23 at 19:33
Using Cython
won't make a significant difference in this problem.
To get a profile/benchmark of your code the Pycharm
IDE has a profiling tool, or you can use kernprof.
However, as a test, you can convert your code to the Cython
code or C
code with these instructions:
[NOTE]:
This approach is for Python3, but it can also be applied to Python2.7 with a few changes. I've tested it before.
[UPDATE]:
You can also use PyInstaller and Nuitka to test another way to convert your code as compiled executable.

- 27,880
- 26
- 135
- 150
-
I agree with the overall sentiment here. As long as you're not doing pixel by pixel operations, OpenCV and Numpy should be pretty fast. Also, when it comes to profiling, using `time.time()` you can figure out how many FPS you get. Start from the end of your code and comment out processing operations. For me, running very simple operations, I typically get 20-30 fps on a 640x480 camera running on a snappy workstation. If I'm getting into more heavy stuff like template matching or keypoint/feature matching it drops further to 10-15 fps. – bfris May 26 '18 at 01:32
-
@bfris yes, I have done this before and I get pretty much 10 fps with the signal processing... Simple collection of frames is usually around 30 fps... – TanMath May 26 '18 at 03:04
It all depends on what your program is doing.
If you program is just stringing together large operations that are implemented in C++ then cython isn't going to help you much if at all.
If you are writing code that works directly on individual pixels then cython could be a big help.

- 9,724
- 2
- 38
- 51