waitkey c++ python performance opencv

c++ - waitkey 0 python



¿El rendimiento difiere entre la codificación Python o C++ de OpenCV? (3)

Como se mencionó en las respuestas anteriores, Python es más lento en comparación con C ++ o C. Python está diseñado por su simplicidad, portabilidad y, además, creatividad donde los usuarios deben preocuparse solo por su algoritmo, no por problemas de programación.

Pero aquí en OpenCV, hay algo diferente. Python-OpenCV es solo una envoltura alrededor del código C / C ++ original. Normalmente se usa para combinar las mejores características de ambos lenguajes, Performance of C / C ++ y Simplicity of Python .

Entonces, cuando llamas a una función en OpenCV desde Python, lo que realmente se ejecuta es una fuente C / C ++ subyacente. Así que no habrá mucha diferencia en el rendimiento. (Recuerdo que leí en algún lado que la penalización de rendimiento es <1%, no recuerdo dónde. Una estimación aproximada con algunas funciones básicas en OpenCV muestra una penalización de peor caso de <4% es decir, penalty = [maximum time taken in Python - minimum time taken in C++]/minimum time taken in C++ ).

El problema surge cuando el código tiene una gran cantidad de códigos python nativos. Por ejemplo, si está realizando sus propias funciones que no están disponibles en OpenCV, las cosas empeoran. Dichos códigos se ejecutan de forma nativa en Python, lo que reduce considerablemente el rendimiento.

Pero la nueva interfaz OpenCV-Python tiene soporte completo para Numpy. Numpy es un paquete para informática científica en Python. También es un envoltorio alrededor del código C nativo. Es una biblioteca altamente optimizada que admite una amplia variedad de operaciones matriciales, muy adecuadas para el procesamiento de imágenes. Entonces, si puede combinar tanto las funciones de OpenCV como las de Numpy correctamente, obtendrá un código de muy alta velocidad.

Lo que hay que recordar es intentar siempre evitar bucles e iteraciones en Python. En su lugar, use los recursos de manipulación de matrices disponibles en Numpy (y OpenCV). Simplemente agregando dos matrices numpy usando C = A+B es mucho más rápido que usar bucles dobles.

Por ejemplo, puede consultar estos artículos:

  1. Manipulación Fast Array en Python
  2. Comparación de rendimiento de las interfaces OpenCV-Python, cv y cv2

Mi objetivo es comenzar con opencv poco a poco, pero primero tengo que decidir qué API de OpenCV es más útil. Predigo que la implementación de Python es más corta, pero el tiempo de ejecución será más denso y lento en comparación con las implementaciones nativas de C ++. ¿Hay algún conocimiento que pueda comentar sobre el rendimiento y las diferencias de codificación entre estas dos perspectivas?


Tienes razón, Python casi siempre es significativamente más lento que C ++, ya que requiere un intérprete, que C ++ no lo hace. Sin embargo, eso requiere que C ++ sea fuertemente tipado, lo que deja un margen de error mucho más pequeño. Algunas personas prefieren que se les haga un código estricto, mientras que otras disfrutan de la indulgencia inherente de Python.

Si desea un discurso completo sobre los estilos de codificación Python y los estilos de codificación C ++, este no es el mejor lugar, intente encontrar un artículo.

EDITAR: debido a que Python es un lenguaje interpretado, mientras que C ++ se compila en código máquina, en general , puede obtener ventajas de rendimiento utilizando C ++. Sin embargo, con respecto al uso de OpenCV, las bibliotecas centrales OpenCV ya están compiladas en código máquina, por lo que el contenedor de Python alrededor de la biblioteca OpenCV está ejecutando código compilado. En otras palabras, cuando se trata de ejecutar algoritmos de OpenCV computacionalmente costosos de Python, no verá mucho éxito en el desempeño ya que ya se han compilado para la arquitectura específica con la que está trabajando.


Todos los resultados de google para openCV dicen lo mismo: que python solo será un poco más lento. Pero ni una vez he visto ningún perfil sobre eso. Así que decidí hacer algo y descubrí:

Python es significativamente más lento que C ++ con opencv, incluso para programas triviales.

El ejemplo más simple que pude pensar fue mostrar la salida de una cámara web en la pantalla y mostrar el número de fotogramas por segundo. Con Python, logré 50FPS (en un átomo de Intel). Con C ++, obtuve 65FPS, un aumento del 25%. En ambos casos, el uso de la CPU utilizaba un solo núcleo, y según mi leal saber y entender, estaba vinculado por el rendimiento de la CPU. Además, este caso de prueba se alinea con lo que he visto en proyectos que pasé de uno al otro en el pasado.

¿De dónde viene esta diferencia? En python, todas las funciones de openCV devuelven nuevas copias de las matrices de imagen. Cada vez que capture una imagen, o si la cambia de tamaño, en C ++ puede reutilizar la memoria existente. En Python no puedes. Sospecho que este tiempo dedicado a asignar memoria es la principal diferencia, porque como otros han dicho: el código subyacente de openCV es C ++.

Antes de lanzar Python fuera de la ventana: python es mucho más rápido para desarrollar, y si no estás corriendo en hardware-constraints, o si la velocidad de desarrollo es más importante que el rendimiento, entonces usa Python. En muchas aplicaciones que he hecho con openCV, he comenzado en python y luego convertí solo los componentes de visión por computadora a C ++ (por ejemplo, usando el módulo de tipo ctype de python y compilando el código CV en una biblioteca compartida).

Código de Python:

import cv2 import time FPS_SMOOTHING = 0.9 cap = cv2.VideoCapture(2) fps = 0.0 prev = time.time() while True: now = time.time() fps = (fps*FPS_SMOOTHING + (1/(now - prev))*(1.0 - FPS_SMOOTHING)) prev = now print("fps: {:.1f}".format(fps)) got, frame = cap.read() if got: cv2.imshow("asdf", frame) if (cv2.waitKey(2) == 27): break

Código C ++:

#include <opencv2/opencv.hpp> #include <stdint.h> using namespace std; using namespace cv; #define FPS_SMOOTHING 0.9 int main(int argc, char** argv){ VideoCapture cap(2); Mat frame; float fps = 0.0; double prev = clock(); while (true){ double now = (clock()/(double)CLOCKS_PER_SEC); fps = (fps*FPS_SMOOTHING + (1/(now - prev))*(1.0 - FPS_SMOOTHING)); prev = now; printf("fps: %.1f/n", fps); if (cap.isOpened()){ cap.read(frame); } imshow("asdf", frame); if (waitKey(2) == 27){ break; } } }

Posibles limitaciones de referencia:

  • Velocidad de cuadros de la cámara
  • Temporizador de medición de precisión
  • Tiempo dedicado al formato impreso