Ich versuche herauszufinden, wie man eine Python-Funktion beschleunigt, die numpy verwendet. Die Ausgabe, die ich von lineprofiler erhalten habe, ist unten, und dies zeigt, dass die meiste Zeit auf der Linie ind_y, ind_x = np.where(seg_image == i)
verbracht wird.Beschleunigen Sie numpy.where zum Extrahieren von Integer-Segmenten?
seg_image
ist ein Integer-Array, das das Ergebnis der Segmentierung eines Bildes ist, und so die Pixel findet, in denen seg_image == i
ein bestimmtes segmentiertes Objekt extrahiert. Ich schlängele mich durch viele dieser Objekte (im Code unten durchlaufe ich nur 5 Tests, aber ich werde tatsächlich mehr als 20.000 durchlaufen), und es dauert sehr lange!
Gibt es eine Möglichkeit, wie der np.where
Anruf beschleunigt werden kann? Oder alternativ, dass die vorletzte Zeile (die auch einen großen Teil der Zeit benötigt) beschleunigt werden kann?
Die ideale Lösung wäre, den Code auf dem gesamten Array auf einmal auszuführen, anstatt Schleifen, aber ich glaube nicht, dass dies möglich ist, da einige der Funktionen, die ich ausführen muss (z Beispielsweise kann das Aufteilen eines segmentierten Objekts dazu führen, dass es mit der nächsten Region kollidiert und somit später falsche Ergebnisse liefert.
Hat jemand irgendwelche Ideen?
Line # Hits Time Per Hit % Time Line Contents
==============================================================
5 def correct_hot(hot_image, seg_image):
6 1 239810 239810.0 2.3 new_hot = hot_image.copy()
7 1 572966 572966.0 5.5 sign = np.zeros_like(hot_image) + 1
8 1 67565 67565.0 0.6 sign[:,:] = 1
9 1 1257867 1257867.0 12.1 sign[hot_image > 0] = -1
10
11 1 150 150.0 0.0 s_elem = np.ones((3, 3))
12
13 #for i in xrange(1,seg_image.max()+1):
14 6 57 9.5 0.0 for i in range(1,6):
15 5 6092775 1218555.0 58.5 ind_y, ind_x = np.where(seg_image == i)
16
17 # Get the average HOT value of the object (really simple!)
18 5 2408 481.6 0.0 obj_avg = hot_image[ind_y, ind_x].mean()
19
20 5 333 66.6 0.0 miny = np.min(ind_y)
21
22 5 162 32.4 0.0 minx = np.min(ind_x)
23
24
25 5 369 73.8 0.0 new_ind_x = ind_x - minx + 3
26 5 113 22.6 0.0 new_ind_y = ind_y - miny + 3
27
28 5 211 42.2 0.0 maxy = np.max(new_ind_y)
29 5 143 28.6 0.0 maxx = np.max(new_ind_x)
30
31 # 7 is + 1 to deal with the zero-based indexing, + 2 * 3 to deal with the 3 cell padding above
32 5 217 43.4 0.0 obj = np.zeros((maxy+7, maxx+7))
33
34 5 158 31.6 0.0 obj[new_ind_y, new_ind_x] = 1
35
36 5 2482 496.4 0.0 dilated = ndimage.binary_dilation(obj, s_elem)
37 5 1370 274.0 0.0 border = mahotas.borders(dilated)
38
39 5 122 24.4 0.0 border = np.logical_and(border, dilated)
40
41 5 355 71.0 0.0 border_ind_y, border_ind_x = np.where(border == 1)
42 5 136 27.2 0.0 border_ind_y = border_ind_y + miny - 3
43 5 123 24.6 0.0 border_ind_x = border_ind_x + minx - 3
44
45 5 645 129.0 0.0 border_avg = hot_image[border_ind_y, border_ind_x].mean()
46
47 5 2167729 433545.8 20.8 new_hot[seg_image == i] = (new_hot[ind_y, ind_x] + (sign[ind_y, ind_x] * np.abs(obj_avg - border_avg)))
48 5 10179 2035.8 0.1 print obj_avg, border_avg
49
50 1 4 4.0 0.0 return new_hot
Das ist wunderbar, fantastisch und erstaunlich - danke! Das erste Mal, als ich es ausführte, stellte ich fest, dass es tatsächlich langsamer war als mein ursprünglicher Code, aber dann habe ich etwas von deinem Code so geändert, dass er die ganze Arbeit (Dilation, Borders usw.) in einem kleinen Array anstatt dem riesigen Array erledigt hat. durch Modifizieren, wie die neue_Form berechnet wurde. Ich habe jetzt eine enorme Geschwindigkeitssteigerung erlebt. Bei einem der Bilder, mit denen ich arbeite, dauerte die alte Version zweieinhalb Stunden, die neue dauerte 11 Sekunden! – robintw
Hoppla! Ja, es sieht so aus, als müsste der Generatorausdruck 'new_shape = tuple (dim + 6 für dim in hot_image_view.shape)' sein und nicht 'new_shape = tuple (dim + 6 für dim in hot_image.shape)' '. Hast du dich verändert? Bitte, fühlen Sie sich frei, meine Antwort zu bearbeiten, um den Arbeitscode widerzuspiegeln. – Jaime