Ich schrieb eine Cython-Funktion, die ein Binärbild (numpy Array) um 1 Pixel erweitert. Deshalb möchte ich einfach den Bereich zu erweitern, wo Array-Werte sind 1. Hier ist mein naiver Ansatz:Leistung: binäre Bild erweitern (morphologische Dilatation)
def expand_1px (numpy.ndarray[numpy.uint8_t, ndim = 2] A):
cdef int h = A.shape[0]
cdef int w = A.shape[1]
cdef numpy.ndarray[numpy.uint8_t, ndim = 2] RES = numpy.zeros([h, w], dtype = numpy.uint8)
# These Two lines below were originally missing
cdef int y, x
cdef unsigned char prev, cur
for x in range (0, w):
for y in range (1, h):
prev = A[y-1,x]
cur = A[y,x]
if cur > prev:
RES[y-1, x] = 1
if cur < prev:
RES[y,x] = 1
for y in range (0, h):
for x in range (1, w):
prev = A[y,x-1]
cur = A[y,x]
if cur > prev:
RES[y, x-1] = 1
if cur < prev:
RES[y,x] = 1
return numpy.bitwise_or(A,RES)
Dies funktioniert korrekt, aber ist kläglich langsam. Eine OpenCV-Funktion dilate() ist ~ 30 mal schneller als meine Cython-Variante und gibt das gleiche Ergebnis. Ich benutze es wie folgt aus:
kernel = numpy.ones((3,3), dtype="uint8")
kernel[0,0] = 0
kernel[2,2] = 0
kernel[0,2] = 0
kernel[2,0] = 0
...
IMG = cv2.dilate(IMG,kernel,iterations = 1)
Q:
- Wie kann so schnell OpenCV die Variante sein? Was macht es eigentlich?
- Wie kann ich meine Cython-Funktion so schnell arbeiten lassen?
aktualisieren:
Eine solche schlechte Leistung war aufgrund fehlender "cdef Erklärungen, mein schlecht. Hinzufügen dieser Funktion macht den Unterschied:
cdef int y, x
cdef unsigned char prev, cur
Immer noch der Leistungsunterschied ist etwa 30 mal, was auch etwas enttäuschend ist. Irgendwelche Ratschläge für weitere Verbesserungen?
* "Wie kann ich meine Cython-Funktion so schnell arbeiten lassen?" * Sie könnten damit beginnen, mehr (vielleicht alle) Ihrer lokalen Variablen zu deklarieren (.eg 'x',' y', 'prev',' cur')) mit dem entsprechenden C-Typ; siehe http://docs.cython.org/src/quickstart/cytholize.html –
@WarrenWeckesser Danke. Du hast natürlich Recht, ich wusste, dass ich wahrscheinlich einen Noob-Fehler mache. Trotzdem ist es ~ 30 mal langsamer als die OpenCV-Variante, ich werde die Frage aktualisieren. –
Haben Sie die Befehlszeile '-a' verwendet, damit der Cython-Befehl eine eingefärbte HTML-Version der Quelle erzeugt? Die dunkelgelben Linien sind Linien, die zu Python-Aufrufen führen, anstatt reines C zu erzeugen. Um die beste Leistung zu erzielen, möchten Sie den Cython-Code optimieren, sodass in den Schleifen kein Gelb angezeigt wird. (Diese Schleifen sehen ziemlich einfach aus. Wenn also alle Variablen C-Deklarationen haben, haben Sie wahrscheinlich keine Python-Aufrufe in den Schleifen.) –