Ich möchte opencv nach und nach starten, aber zuerst muss ich entscheiden, welche API von OpenCV nützlicher ist. Ich gehe davon aus, dass die Python-Implementierung kürzer ist, die Laufzeit jedoch im Vergleich zu den nativen C ++ - Implementierungen dichter und langsamer sein wird. Gibt es irgendwelche bekannten Kommentare zu Leistungs- und Codierungsunterschieden zwischen diesen beiden Perspektiven?
c++
python
performance
opencv
erogol
quelle
quelle
C
ohnehin hinter den Kulissen vom OpenCV- Code erledigt. Vorausgesetzt , Ihr eigener Code ist nicht zu aufwendig, sollte der Unterschied nicht so groß sein, wie Sie es naiv erwarten würden.Antworten:
Wie bereits in früheren Antworten erwähnt, ist Python im Vergleich zu C ++ oder C langsamer. Python wurde aufgrund seiner Einfachheit, Portabilität und Kreativität entwickelt, bei der sich Benutzer nur um ihren Algorithmus und nicht um Programmierprobleme kümmern müssen.
Aber hier in OpenCV gibt es etwas anderes. Python-OpenCV ist nur ein Wrapper um den ursprünglichen C / C ++ - Code. Es wird normalerweise verwendet, um die besten Funktionen beider Sprachen, die Leistung von C / C ++ und die Einfachheit von Python , zu kombinieren .
Wenn Sie also eine Funktion in OpenCV von Python aus aufrufen, liegt tatsächlich die zugrunde liegende C / C ++ - Quelle zugrunde. Es wird also keinen großen Unterschied in der Leistung geben. (Ich erinnere mich, dass ich irgendwo gelesen habe, dass die Leistungsstrafe <1% ist, weiß nicht, wo. Eine grobe Schätzung mit einigen Grundfunktionen in OpenCV zeigt eine Strafe im schlimmsten Fall von
<4%
. Dhpenalty = [maximum time taken in Python - minimum time taken in C++]/minimum time taken in C++
) .Das Problem tritt auf, wenn Ihr Code viele native Python-Codes enthält. Wenn Sie beispielsweise eigene Funktionen erstellen, die in OpenCV nicht verfügbar sind, wird es schlimmer. Solche Codes werden nativ in Python ausgeführt, was die Leistung erheblich verringert.
Die neue OpenCV-Python-Oberfläche unterstützt Numpy jedoch vollständig. Numpy ist ein Paket für wissenschaftliches Rechnen in Python. Es ist auch ein Wrapper um nativen C-Code. Es handelt sich um eine hochoptimierte Bibliothek, die eine Vielzahl von Matrixoperationen unterstützt und sich hervorragend für die Bildverarbeitung eignet. Wenn Sie also sowohl OpenCV-Funktionen als auch Numpy-Funktionen korrekt kombinieren können, erhalten Sie einen sehr schnellen Code.
Denken Sie immer daran, Schleifen und Iterationen in Python zu vermeiden. Verwenden Sie stattdessen Array-Manipulationsfunktionen, die in Numpy (und OpenCV) verfügbar sind. Das einfache Hinzufügen von zwei Numpy-Arrays mit
C = A+B
ist viel schneller als das Verwenden von Doppelschleifen.Zum Beispiel können Sie diese Artikel überprüfen:
quelle
Alle Google-Ergebnisse für openCV geben den gleichen Status an: Dieser Python ist nur geringfügig langsamer. Aber ich habe kein einziges Mal ein Profiling dazu gesehen. Also entschied ich mich für einige und entdeckte:
Python ist mit opencv deutlich langsamer als C ++, selbst für triviale Programme.
Das einfachste Beispiel, das ich mir vorstellen konnte, war, die Ausgabe einer Webcam auf dem Bildschirm anzuzeigen und die Anzahl der Bilder pro Sekunde anzuzeigen. Mit Python erreichte ich 50 FPS (auf einem Intel-Atom). Mit C ++ habe ich 65 FPS erhalten, eine Steigerung von 25%. In beiden Fällen verwendete die CPU-Auslastung einen einzigen Kern und war meines Wissens an die Leistung der CPU gebunden. Außerdem stimmt dieser Testfall mit dem überein, was ich in Projekten gesehen habe, die ich in der Vergangenheit von einem zum anderen portiert habe.
Woher kommt dieser Unterschied? In Python geben alle openCV-Funktionen neue Kopien der Bildmatrizen zurück. Wann immer Sie ein Bild aufnehmen oder dessen Größe ändern - in C ++ können Sie den vorhandenen Speicher wiederverwenden. In Python können Sie nicht. Ich vermute, dass diese Zeit für die Zuweisung von Speicher der Hauptunterschied ist, denn wie andere gesagt haben: Der zugrunde liegende Code von openCV ist C ++.
Bevor Sie Python aus dem Fenster werfen: Python lässt sich viel schneller entwickeln. Wenn Sie nicht auf Hardwareeinschränkungen stoßen oder wenn die Entwicklungsgeschwindigkeit wichtiger ist als die Leistung, verwenden Sie Python. In vielen Anwendungen, die ich mit openCV ausgeführt habe, habe ich in Python begonnen und später nur die Computer Vision-Komponenten in C ++ konvertiert (z. B. mithilfe des ctype-Moduls von Python und Kompilieren des CV-Codes in eine gemeinsam genutzte Bibliothek).
Python-Code:
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 ++ - Code:
#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; } } }
Mögliche Benchmark-Einschränkungen:
quelle
dst = cv2.filter2D(img, -1, kernel)
erstellt der Computer eine Kopie vonimg
und gibt sie als zurückdst
. Wenn Sie nicht verwenden,img
kommt der GC und bereinigt das alte Bild. Mit der openCV-Python-API führt kein Weg daran vorbei. In C / C ++ können Sie problemlos einen statischen Bildpuffer mit der richtigen Größe erstellen, der nicht bei jedem Frame erstellt / zerstört wird. Die Zeit für Speicherzuweisungen und Freigabe ist nicht Null.Der Antwort von sdfgeoff fehlt die Tatsache, dass Sie Arrays in Python wiederverwenden können . Ordnen Sie sie vor und geben Sie sie weiter, und sie werden sich daran gewöhnen. Damit:
image = numpy.zeros(shape=(height, width, 3), dtype=numpy.uint8) #.... retval, _ = cv.VideoCapture.read(image)
quelle
Sie haben Recht, Python ist fast immer deutlich langsamer als C ++, da es einen Interpreter erfordert, was C ++ nicht tut. Dies erfordert jedoch eine starke Typisierung von C ++, wodurch eine viel geringere Fehlerquote verbleibt. Einige Leute ziehen es vor, strikt zu codieren, während andere Pythons inhärente Nachsicht genießen.
Wenn Sie einen vollständigen Diskurs über Python-Codierungsstile im Vergleich zu C ++ - Codierungsstilen wünschen, ist dies nicht der beste Ort. Versuchen Sie, einen Artikel zu finden.
BEARBEITEN: Da Python eine interpretierte Sprache ist, während C ++ im Allgemeinen zu Maschinencode kompiliert wird , können Sie mit C ++ Leistungsvorteile erzielen. In Bezug auf die Verwendung von OpenCV sind die OpenCV-Kernbibliotheken jedoch bereits zu Maschinencode kompiliert, sodass der Python-Wrapper um die OpenCV-Bibliothek kompilierten Code ausführt. Mit anderen Worten, wenn es darum geht, rechenintensive OpenCV-Algorithmen aus Python auszuführen, werden Sie keinen großen Leistungseinbruch feststellen, da diese bereits für die spezifische Architektur kompiliert wurden, mit der Sie arbeiten.
quelle