我正在使用 Numpy 执行图像处理,特别是运行标准偏差拉伸。这会读入 X 列,找到 Std。并执行百分比线性拉伸。然后它迭代到下一个“组”列并执行相同的操作。输入图像是一个 1GB 的 32 位单波段栅格,需要相当长的时间来处理(小时)。下面是代码。
我意识到我有 3 个嵌套的 for 循环,这可能是瓶颈发生的地方。如果我在“盒子”中处理图像,也就是说加载一个 [500,500] 的数组并迭代图像处理时间非常短。不幸的是,相机错误要求我迭代极长的条带 (52,000 x 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) )
这是一个更新:不使用配置文件模块,因为我不想开始将一小部分代码包装到函数中,所以我混合使用了 print 和 exit 语句来大致了解哪些行花费的时间最多。幸运的是(而且我确实理解我是多么幸运)一条线拖累了一切。
outRaster = outdataset.GetRasterBand(j).WriteArray(outputBlock,h,i)#array, xOffset, yOffset
在打开输出文件并写出数组时,GDAL 似乎效率很低。考虑到这一点,我决定将修改后的数组“outBlock”添加到 python 列表中,然后写出块。这是我更改的部分:
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 并了解向量化以进行额外优化。