تکرار سرعت در آرایه های پراکنده

من در حال کار بر روی پردازش تصویر با استفاده از Numpy ، به طور خاص یک کشش انحراف استاندارد در حال اجرا هستم. این در ستون X می خواند ، Std پیدا می شود. و درصد کشش خطی را انجام می دهد. سپس به "گروه" ستون های بعدی تکرار می شود و همان عملیات را انجام می دهد. تصویر ورودی یک رستر 1 گیگابایتی ، 32 بیتی ، تک باند است که پردازش آن (ساعت ها) بسیار طولانی است. در زیر کد

من متوجه می شوم که من 3 حلقه قرار داده ام ، که احتمالاً در آنجا گلوگاه اتفاق می افتد. اگر تصویر را در "جعبه ها" پردازش کنم ، به این معنی است که بارگیری آرایه ای [500،500] و تکرار در زمان پردازش تصویر بسیار کوتاه است. متأسفانه ، خطای دوربین مستلزم تکرار در نوارهای بسیار طولانی (52000 4 4) (y ، x) برای جلوگیری از ایجاد باند است.

هر گونه پیشنهاد در مورد سرعت بخشیدن به این مورد قابل تقدیر است:

def box(dataset, outdataset, sampleSize, n):

    quiet = 0
    sample = sampleSize
    #iterate over all of the bands
    for j in xrange(1, dataset.RasterCount + 1): #1 based counter

        band = dataset.GetRasterBand(j)
        NDV = band.GetNoDataValue()

        print "Processing band: " + str(j)       

        #define the interval at which blocks are created
        intervalY = int(band.YSize/1)    
        intervalX = int(band.XSize/2000) #to be changed to sampleSize when working

        #iterate through the rows
        scanBlockCounter = 0

        for i in xrange(0,band.YSize,intervalY):

            #If the next i is going to fail due to the edge of the image/array
            if i + (intervalY*2) < band.YSize:
                numberRows = intervalY
            else:
                numberRows = band.YSize - i

            for h in xrange(0,band.XSize, intervalX):

                if h + (intervalX*2) < band.XSize:
                    numberColumns = intervalX
                else:
                    numberColumns = band.XSize - h

                scanBlock = band.ReadAsArray(h,i,numberColumns, numberRows).astype(numpy.float)

                standardDeviation = numpy.std(scanBlock)
                mean = numpy.mean(scanBlock)

                newMin = mean - (standardDeviation * n)
                newMax = mean + (standardDeviation * n)

                outputBlock = ((scanBlock - newMin)/(newMax-newMin))*255
                outRaster = outdataset.GetRasterBand(j).WriteArray(outputBlock,h,i)#array, xOffset, yOffset


                scanBlockCounter = scanBlockCounter + 1
                #print str(scanBlockCounter) + ": " + str(scanBlock.shape) + str(h)+ ", " + str(intervalX)
                if numberColumns == band.XSize - h:
                    break

                #update progress line
                if not quiet:
                    gdal.TermProgress_nocb( (float(h+1) / band.YSize) )

در اینجا یک به روزرسانی وجود دارد: بدون استفاده از ماژول پروفایل ، چون نمی خواستم بخشهای کوچکی از کد را در توابع قرار دهم ، از ترکیبی از دستورات چاپ و خروج استفاده کردم تا یک ایده تقریباً دقیق درباره اینکه کدام خطها بیشترین زمان را می گیرند ، بگیرم. خوشبختانه (و من می دانم که چقدر خوش شانس بودم) یک خط همه چیز را به سمت پایین می کشید.

    outRaster = outdataset.GetRasterBand(j).WriteArray(outputBlock,h,i)#array, xOffset, yOffset

به نظر می رسد GDAL هنگام باز کردن پرونده خروجی و نوشتن آرایه کاملاً ناکارآمد است. با توجه به این نکته ، تصمیم گرفتم آرایه های اصلاح شده خود را "outBlock" به لیست پایتون اضافه کنم ، سپس بخشهای مختلف را بنویسم. در اینجا بخشی را تغییر داده ام:

OutputBlock فقط اصلاح شد ...

         #Add the array to a list (tuple)
            outputArrayList.append(outputBlock)

            #Check the interval counter and if it is "time" write out the array
            if len(outputArrayList) >= (intervalX * writeSize) or finisher == 1:

                #Convert the tuple to a numpy array.  Here we horizontally stack the tuple of arrays.
                stacked = numpy.hstack(outputArrayList)

                #Write out the array
                outRaster = outdataset.GetRasterBand(j).WriteArray(stacked,xOffset,i)#array, xOffset, yOffset
                xOffset = xOffset + (intervalX*(intervalX * writeSize))

                #Cleanup to conserve memory
                outputArrayList = list()
                stacked = None
                finisher=0

Finisher به سادگی یک پرچم است که لبه ها را کنترل می کند. کمی طول کشید تا بفهمید که چگونه می توان یک آرایه از لیست ساخت. در این صورت ، با استفاده از numpy.array یک آرایه 3-d ایجاد می شد (کسی به شما توضیح می دهد چرا؟) و نوشتن آرایه به یک آرایه 2d احتیاج دارد. زمان کل پردازش اکنون از کمتر از 2 دقیقه تا 5 دقیقه متفاوت است. آیا ایده ای وجود دارد که چرا دامنه های زمانی ممکن است وجود داشته باشد؟

با تشکر فراوان از همه کسانی که ارسال کردند! گام بعدی این است که واقعاً وارد Numpy شوید و در مورد بردارسازی برای بهینه سازی اضافی بیاموزید.

7
задан Jzl5325 12 July 2011 в 17:36
поделиться