मेरे पास एक छवि है जिस पर मैं कुछ गणना करना चाहता हूं। छवि पिक्सेल को f(x, y) के रूप में दर्शाया जाएगा जहां x कॉलम संख्या है और y प्रत्येक पिक्सेल की पंक्ति संख्या है। मैं निम्नलिखित सूत्र का उपयोग करके गणना करना चाहता हूं:

enter image description here

यहां वह कोड है जो गणना करता है:

import matplotlib.pyplot as plt
import numpy as np
import os.path
from PIL import Image

global image_width, image_height


# A. Blur Measurement
def  measure_blur(f):

    D_sub_h = [[0 for y in range(image_height)] for x in range(image_width)]

    for x in range(image_width):
        for y in range(image_height):
            if(y == 0):                
                f_x_yp1 = f[x][y+1]
                f_x_ym1 = 0 
            elif(y == (image_height -1)):

                f_x_yp1 = 0
                f_x_ym1 = f[x][y -1]
            else:                
                f_x_yp1 = f[x][y+1]
                f_x_ym1 = f[x][y -1]

            D_sub_h[x][y] = abs(f_x_yp1 - f_x_ym1)

    return D_sub_h

if __name__ == '__main__':

    image_counter = 1

    while True:

        if not os.path.isfile(str (image_counter) + '.jpg'):
            break

        image_path = str(image_counter) + '.jpg'
        image = Image.open(image_path )
        image_height, image_width = image.size

        print("Image Width : " + str(image_width))
        print("Image Height : " + str(image_height))

        f = np.array(image)
        D_sub_h = measure_blur(f)
        image_counter = image_counter + 1

इस कोड के साथ समस्या यह है कि जब छवि का आकार बड़ा हो जाता है, जैसे (5000, 5000), तो इसे पूरा होने में बहुत लंबा समय लगता है। क्या कोई तरीका या कार्य है जिसका उपयोग मैं एक-एक करके या मैन्युअल गणना न करके निष्पादन समय को तेज करने के लिए कर सकता हूं?

1
alyssaeliyah 26 मार्च 2020, 20:58

1 उत्तर

सबसे बढ़िया उत्तर

चूंकि आप विशेष रूप से इनपुट f को एक numpy सरणी में परिवर्तित करते हैं, मुझे लगता है कि आप numpy का उपयोग करना चाहते हैं। उस स्थिति में, D_sub_h के आवंटन को सूची से एक सरणी में बदलना होगा:

D_sub_h = np.empty_like(f)

यदि हम मानते हैं कि आपके सरणी के बाहर सब कुछ शून्य है, तो पहली पंक्ति और अंतिम पंक्ति की गणना क्रमशः दूसरी और नकारात्मक दूसरी-से-अंतिम पंक्तियों के रूप में की जा सकती है:

D_sub_h[0, :] = f[1, :]
D_sub_h[-1, :] = -f[-2, :]

शेष डेटा प्रत्येक स्थान पर अगले और पिछले सूचकांक के बीच का अंतर है, जिसे मुहावरेदार रूप से दृश्यों को स्थानांतरित करके गणना की जाती है: f[2:, :] - f[:-2, :]। यह सूत्रीकरण एक अस्थायी सरणी बनाता है। आप np.subtract स्पष्ट रूप से:

np.subtract(f[2:, :], f[:-2, :], out=D_sub_h[1:-1, :])

इस फॉर्मूलेशन में पूरी चीज चार लाइनें लेती है, और पूरी तरह से वेक्टरकृत होती है, जिसका अर्थ है कि लूप हुड के नीचे तेजी से चलते हैं, बिना अधिकांश पायथन के ओवरहेड के:

def measure_blur(f):
    D_sub_h = np.empty_like(f)
    D_sub_h[0, :] = f[1, :]
    D_sub_h[-1, :] = -f[-2, :]
    np.subtract(f[2:, :], f[:-2, :], out=D_sub_h[1:-1, :])
    return D_sub_h

ध्यान दें कि मैं इसे प्रिंट करने के बजाय मूल्य वापस कर देता हूं। जब आप फ़ंक्शन लिखते हैं, तो मान वापस करने की आदत डालें। मुद्रण बाद में किया जा सकता है, और यदि यह उचित रिटर्न की जगह लेता है तो गणना को प्रभावी ढंग से त्याग देता है।

ऊपर दिखाया गया तरीका समय और स्थान के संबंध में काफी कुशल है। यदि आप एक लाइनर लिखना चाहते हैं जो बहुत से अस्थायी सरणी का उपयोग करता है, तो आप यह भी कर सकते हैं:

D_sub_h = np.concatenate((f[1, None], f[2:, :] - f[:-2, :], -f[-2, None]), axis=0)
1
Mad Physicist 26 मार्च 2020, 20:49