2010-02-17 16 views
7

में स्क्वायर मतभेदों (एसएसडी) का योग एक छवि प्रसंस्करण एल्गोरिदम लागू करने के लिए मैं पाइथन और न्यूम्पी/सिसी का उपयोग करने की कोशिश कर रहा हूं। प्रोफाइलर मुझसे कहता है बहुत समय निम्नलिखित समारोह (अक्सर कहा जाता है) में खर्च किया जा रहा है, जो मुझे दो छवियोंnumpy/scipy

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

मैं इस में तेजी लाने के कर सकते हैं कैसे के बीच वर्ग मतभेद का योग कहता है? धन्यवाद।

उत्तर

27

बस

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

(जो मैं उम्मीद आकार हमेशा है अगर (,, 3) होने की संभावना सिर्फ sum((A-B)**2) है)

तुम भी योग पद्धति का उपयोग कर सकते हैं: ((A-B)**2).sum()

सही?

+2

बैंग में इस लक्ष्य को हासिल कर सकते हैं। मुझे धीमा दिन हो रहा है मेरे चलने का समय हल करता है। –

+0

यह ध्यान देने योग्य है कि इसके लिए आपको 'numpy.sum' का उपयोग करना होगा, न कि बिल्टिन' sum', जो पहले आयाम पर योग पाएगा और एक आयाम-निचले स्तर की एक नई सरणी लौटाएगा। –

+0

((ए-बी) ** 2) .sum (-1) यदि आप केवल अंतिम धुरी को जोड़ना चाहते हैं, तो धुरी तर्क को निर्दिष्ट करने की आवश्यकता है। बस राशि का उपयोग करके() सरणी की सभी प्रविष्टियों को जोड़ता है (पहले raveled) – user333700

1

मुझे नहीं पता कि पावर 2 के साथ पावर() फ़ंक्शन तेज़ होगा या नहीं। प्रयास करें:

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

मैं उलझन में हूँ तुम क्यों i in range(3) ले रहे हैं। क्या यह पूरी सरणी या सिर्फ एक हिस्सा होना चाहिए?

कुल मिलाकर, आप numpy में परिभाषित कार्यों के साथ इस का सबसे जगह ले सकता है:

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

इस तरह आप तीन के बजाय एक आपरेशन कर सकते हैं और numpy.sum का उपयोग कर इसके अंतर्निहित sum की तुलना में बेहतर अनुकूलन करने के लिए सक्षम हो सकता है ।

+2

+1 इस प्रकार 'scipy.stats.stats.ss' (वर्गों का योग) करता है। – unutbu

1

Ritsaert Hornstra के जवाब यह है कि 2 नकारात्मक अंक मिले (वैसे मैं इसे नहीं देखा यह मूल रूप है में ...)

को आगे यह वास्तव में सच है।

बड़ी संख्या में पुनरावृत्तियों के लिए अक्सर '**' ऑपरेटर या पाउ (एक्स, वाई) विधि का उपयोग करने के लिए दो बार अधिक समय लग सकता है ताकि मैन्युअल रूप से जोड़े को मैन्युअल रूप से गुणा किया जा सके। यदि आवश्यक हो तो math.fabs() विधि का उपयोग करें यदि यह NaN को फेंक रहा है (जो कभी-कभी विशेष रूप से int16s आदि का उपयोग करते समय करता है), और यह अभी भी केवल दो कार्यों के आधा समय लेता है।

मुझे पता है कि मूल प्रश्न के लिए महत्वपूर्ण नहीं है, लेकिन निश्चित रूप से जानने के लायक है।

-3

रूबी भाषा में आप इस तरह से

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