web-dev-qa-db-fra.com

Les performances diffèrent-elles entre le codage Python ou C++ d’OpenCV?

Je souhaite commencer à s’ouvrir petit à petit, mais je dois d’abord décider quelle API d’OpenCV est la plus utile. Je prédis que l'implémentation Python est plus courte, mais que le temps d'exécution sera plus dense et lent que les implémentations C++ natives. Est-ce que quelqu'un sait commenter les performances et les différences de codage entre ces deux perspectives?

51
erogol

Comme mentionné dans les réponses précédentes, Python est plus lent que C++ ou C. Python est conçu pour sa simplicité, sa portabilité et, en outre, sa créativité où les utilisateurs doivent se préoccuper uniquement de leur algorithme, pas de problèmes de programmation.

Mais ici, dans OpenCV, il y a quelque chose de différent. Python-OpenCV est juste un wrapper autour du code C/C++ d'origine. Il est normalement utilisé pour combiner les meilleures fonctionnalités des deux langages, Performances de C/C++ et Simplicité de Python.

Ainsi, lorsque vous appelez une fonction OpenCV à partir de Python, ce qui est réellement exécuté est une source C/C++ sous-jacente. Il n’y aura donc pas beaucoup de différence dans les performances (je me souviens avoir lu quelque part que la pénalité de performance est <1%, je ne me souviens plus où. Une estimation approximative comportant quelques fonctions de base dans OpenCV indique une pénalité de pire-cas de <4%. ie penalty = [maximum time taken in Python - minimum time taken in C++]/minimum time taken in C++).

Le problème se pose lorsque votre code contient beaucoup de codes python natifs. Par exemple, si vous créez vos propres fonctions qui ne sont pas disponibles dans OpenCV, la situation empire. De tels codes sont exécutés nativement en Python, ce qui réduit considérablement les performances. 

Mais la nouvelle interface OpenCV-Python prend totalement en charge Numpy. Numpy est un package pour l'informatique scientifique en Python. C'est également un wrapper autour du code C natif. Il s’agit d’une bibliothèque hautement optimisée prenant en charge une grande variété d’opérations matricielles, parfaitement adaptée au traitement des images. Donc, si vous pouvez combiner correctement les fonctions OpenCV et Numpy, vous obtiendrez un code très rapide.

Rappelez-vous, essayez toujours d'éviter les boucles et les itérations en Python. Utilisez plutôt les fonctionnalités de manipulation de tableaux disponibles dans Numpy (et OpenCV). Ajouter simplement deux tableaux numpy à l'aide de C = A+B est beaucoup plus rapide que d'utiliser des boucles doubles.

Par exemple, vous pouvez vérifier ces articles: 

  1. Manipulation rapide de tableaux en Python
  2. Comparaison des performances des interfaces OpenCV-Python, cv et cv2
121
Abid Rahman K

Tous les résultats de Google pour openCV sont identiques: ce python ne sera que légèrement plus lent. Mais pas une seule fois je n’ai vu de profilage à ce sujet. J'ai donc décidé d'en faire et j'ai découvert:

Python est nettement plus lent que C++ avec opencv, même pour des programmes triviaux.

L'exemple le plus simple auquel je pouvais penser était d'afficher la sortie d'une webcam à l'écran et d'afficher le nombre d'images par seconde. Avec python, j’ai atteint 50FPS (sur un atome d’Intel). Avec C++, j'ai 65 images par seconde, soit une augmentation de 25%. Dans les deux cas, l'utilisation du processeur utilisait un seul cœur et, à ma connaissance, était liée aux performances du processeur. En outre, ce scénario de test correspond à ce que j’ai vu dans les projets que j’ai transférés de l’un à l’autre dans le passé.

D'où vient cette différence? En python, toutes les fonctions openCV renvoient de nouvelles copies des matrices d'images. Chaque fois que vous capturez une image ou si vous la redimensionnez - en C++, vous pouvez réutiliser la mémoire existante. En python, vous ne pouvez pas. Je soupçonne que ce temps passé à allouer de la mémoire est la différence majeure, car, comme d’autres l’ont déjà dit: le code sous-jacent d’openCV est C++.

Avant de lancer python par la fenêtre: le développement de python est beaucoup plus rapide, et si vous ne rencontrez pas de contraintes matérielles, ou si la vitesse de développement est plus importante que les performances, utilisez python. Dans de nombreuses applications que j'ai réalisées avec openCV, j'ai démarré en python, puis converti uniquement les composants de vision par ordinateur en C++ (par exemple, en utilisant le module ctype de python et en compilant le code CV dans une bibliothèque partagée). 

Code 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

Code 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;
        }
    }
}

Limites de référence possibles:

  • Cadence de la caméra
  • Minuterie mesure précision
  • Temps passé au formatage d'impression
6
sdfgeoff

Vous avez raison, Python est presque toujours beaucoup plus lent que C++ car il nécessite un interpréteur, contrairement à C++. Cependant, cela nécessite que C++ soit fortement typé, ce qui laisse une marge d'erreur beaucoup plus petite. Certaines personnes préfèrent être obligées de coder strictement, tandis que d'autres apprécient la clémence inhérente à Python.

Si vous souhaitez avoir un discours complet sur les styles de codage Python par rapport aux styles de codage C++, ce n'est pas le meilleur endroit, essayez de trouver un article.

EDIT: Comme Python est un langage interprété, alors que C++ est compilé en code machine,, d’une manière générale, vous pouvez obtenir des avantages en termes de performances grâce à C++. Cependant, en ce qui concerne l'utilisation d'OpenCV, les bibliothèques OpenCV principales sont déjà compilées en code machine. Le wrapper Python autour de la bibliothèque OpenCV exécute le code compilé. En d’autres termes, lorsqu’il s’agit d’exécuter des algorithmes OpenCV de Python, qui sont très coûteux en calcul, les performances ne seront guère affectées, car ils ont déjà été compilés pour l’architecture spécifique avec laquelle vous travaillez.

3
Callum McLean