यहां एक दृष्टिकोण है जो V2
से काफी तेज़ है: img1-img2
लें, और img1>img2
पर निर्भर करते हुए 1 या -1 से गुणा करें। यह इस प्रकार से कार्यान्वित किया जाता है है:
def differenceImageV6(img1, img2):
a = img1-img2
b = np.uint8(img1<img2) * 254 + 1
return a * b
परीक्षण प्रदर्शन के लिए एक परीक्षण दोहन:
import numpy as np
img1=np.uint8(np.random.randint(0, 255, (480, 640)))
img2=np.uint8(np.random.randint(0, 255, (480, 640)))
def differenceImageV1(img1, img2):
diff=np.empty_like(img1)
h, w=img1.shape
for y in range(h):
for x in range(w):
if img1[y, x]<img2[y, x]: diff[y, x]=img2[y, x]-img1[y, x]
else: diff[y, x]=img1[y, x]-img2[y, x]
return(diff)
def differenceImageV2(img1, img2):
return(np.uint8(np.abs(np.int16(img1)-img2)))
def differenceImageV3(img1, img2): # fast - but wrong result
return(img1-img2)
def differenceImageV4(img1, img2):
return np.where(img1>img2, img1-img2, img2-img1)
def differenceImageV5(img1, img2):
a = img1-img2
b = img2-img1
c = img1>img2
return a*c + b*(~c)
def differenceImageV6(img1, img2):
a = img1-img2
b = np.uint8(img1<img2) * 254 + 1
return a * b
import timeit
def testit():
for fn in [differenceImageV2, differenceImageV3, differenceImageV4, differenceImageV5, differenceImageV6]:
print fn.__name__, np.sum(fn(img1, img2).astype('int64')),
print timeit.timeit("%s(img1, img2)" % fn.__name__, "from test import img1, img2, %s" % fn.__name__, number=1000)
if __name__ == '__main__':
testit()
और जिसके परिणामस्वरूप प्रदर्शन संख्या:
differenceImageV2 26071358 0.982538938522
differenceImageV3 39207702 0.0261280536652
differenceImageV4 26071358 1.36270809174
differenceImageV5 26071358 0.220561981201
differenceImageV6 26071358 0.154536962509
differenceImageV6
, गलत differenceImageV3
से के बारे में 6x धीमी है लेकिन पिछले सबसे अच्छे differenceImageV2
की तुलना में अभी भी 6x तेज है। differenceImageV1
परीक्षण नहीं किया गया है क्योंकि यह बाकी की तुलना में धीमी गति के कुछ आदेश आसानी से धीमा है।
नोट: मैंने तुलना के लिए np.where
दृष्टिकोण शामिल किया है; मैंने सोचा कि इसका अच्छा प्रदर्शन हो सकता है लेकिन यह काफी खराब साबित हुआ है। ऐसा लगता है कि एक बूलियन सरणी द्वारा स्लाइसिंग प्रदर्शन NumPy में काफी धीमी है।
यह सुनिश्चित नहीं है कि यह वास्तव में बहुत मदद करेगा, लेकिन संभवतया आपको 'अंतर ImageV2' में 'np.int16 (img2)' की आवश्यकता नहीं है, और केवल' img2' का उपयोग कर सकते हैं। साथ ही, क्या आप सटीक समय के परिणामों के लिए ['timeit'] (https://docs.python.org/2/library/timeit.html) लाइब्रेरी का उपयोग कर रहे हैं? – Kupiakos
मुझे ओवरफ्लो के बारे में पता है (अंडरफ्लो तब होता है जब दो फ़्लोटिंग पॉइंट नंबरों के बीच का अंतर अलग-अलग बनने के लिए बहुत छोटा होता है)। मेरा मतलब है कि पूरा बयान 'वापसी (np.uint8 (np.absolute (np.int16 (img1) -img2) होगा)। 'img1' अभी भी' int16' पर डाला गया है, इसलिए परिणाम 'int16' होगा और उसी ऋणात्मक संख्या को अनुमति दे सकता है जो पहले से ही कास्ट कर देगा। 'np.sum' एक ही परिणाम देता है। यह सिर्फ पूरे सरणी की एक प्रति नहीं लेता है। मैं 1000 लूप के लिए लगभग 70 एमएस बंद कर देता हूं। – Kupiakos
आप सही हैं। मुझे एक ही परिणाम मिलता है, अगर मैं 'np.int16 (img1) -img2' करता हूं। 1000 लूप के लिए निष्पादन समय 400.3 9 एमएस तक चला जाता है। और नहीं, मैं 'time.process_time() 'का उपयोग यहां करता हूं, क्योंकि मुझे एक या दस मिलीसेकंड की परवाह नहीं है। – dede