2010-02-17 14 views
7

Ich versuche Python und Numpy/Scipy zu verwenden, um einen Bildverarbeitungsalgorithmus zu implementieren. Der Profiler sagt mir viel Zeit wird in der folgenden Funktion (häufig genannt) ausgegeben, was mir die Summe der quadratischen Differenzen zwischen zwei BildernSumme quadratischer Unterschiede (SSD) in numpy/scipy

def ssd(A,B): 
    s = 0 
    for i in range(3): 
     s += sum(pow(A[:,:,i] - B[:,:,i],2)) 
    return s 

erzählt Wie kann ich das beschleunigen? Vielen Dank.

Antwort

27

Gerade

s = numpy.sum((A[:,:,0:3]-B[:,:,0:3])**2) 

(was ich erwarte, dass wahrscheinlich nur sum((A-B)**2), wenn die Form immer (,, 3))

Sie können auch die Summe Methode: ((A-B)**2).sum()

Recht?

+2

Bang. Ich habe einen langsamen Tag. Halbiert meine Laufzeit. –

+0

Es ist erwähnenswert, dass Sie dazu 'numpy.sum' verwenden müssen, nicht die eingebaute' Summe', die die Summe über der ersten Dimension findet und ein neues Array von einer Dimension-niedriger zurückgibt. –

+0

((A-B) ** 2) .sum (-1) Wenn Sie nur die letzte Achse hinzufügen möchten, muss das Achsenargument angegeben werden. Die Verwendung von sum() fügt alle Einträge des Arrays hinzu (zuerst geplättet) – user333700

1

Ich weiß nicht, ob die pow() Funktion mit Power 2 schnell sein wird. Versuchen:

def ssd(A,B): 
    s = 0 
    for i in range(3): 
     s += sum((A[:,:,i] - B[:,:,i])*A[:,:,i] - B[:,:,i]) 
    return s 
1

Ich bin verwirrt, warum Sie i in range(3) einnehmen. Soll das das ganze Array sein oder nur ein Teil?

def ssd(A,B): 
    squares = (A[:,:,:3] - B[:,:,:3]) ** 2 
    return numpy.sum(squares) 

So kann man statt drei eine Operation tun kann und numpy.sum verwendet, kann der Lage sein, die Zugabe besser als die builtin zu optimieren sum:

Insgesamt können Sie die meisten dieser mit Operationen in numpy definiert ersetzen .

+2

+1 Dies ist, wie 'scipy.stats.stats.ss' (Summe der Quadrate) es tut. – unutbu

1

Weitere zu Ritsaert Hornstra Antwort, die zwei negativen Noten bekam (zugegebenermaßen habe ich es nicht gesehen in seiner ursprünglichen Form ist ...)

Dies ist tatsächlich wahr.

Für eine große Anzahl von Iterationen kann es oft doppelt so lange dauern, den '**' Operator oder die pow (x, y) Methode zu verwenden, um die Paare einfach manuell zu multiplizieren. Verwenden Sie ggf. die Methode math.fabs(), wenn sie NaNs auswirft (was sie insbesondere bei Verwendung von int16s usw. tut), und es dauert immer noch nur etwa die Hälfte der Zeit der beiden angegebenen Funktionen.

Nicht so wichtig zu der ursprünglichen Frage, die ich weiß, aber auf jeden Fall wissenswert.

-3

In Ruby Sprache können Sie dies auf diese Weise erreichen

def diff_btw_sum_of_squars_and_squar_of_sum(from=1,to=100) # use default values from 1..100. 
((1..100).inject(:+)**2) -(1..100).map {|num| num ** 2}.inject(:+) 
end 

diff_btw_sum_of_squars_and_squar_of_sum #call for above method