我正在尝试使用GDAL和Python实现最小距离算法以进行图像分类。在计算了样本区域的平均像素值并将它们存储到数组列表(“sample_array”)之后,我将图像读入一个名为“values”的数组中。使用以下代码,我遍历此数组:
values = valBD.ReadAsArray()
# loop through pixel columns
for X in range(0,XSize):
# loop thorugh pixel lines
for Y in range (0, YSize):
# initialize variables
minDist = 9999
# get minimum distance
for iSample in range (0, sample_count):
# dist = calc_distance(values[jPixel, iPixel], sample_array[iSample])
# computing minimum distance
iPixelVal = values[Y, X]
mean = sample_array[iSample]
dist = math.sqrt((iPixelVal - mean) * (iPixelVal - mean)) # only for testing
if dist < minDist:
minDist = dist
values[Y, X] = iSample
classBD.WriteArray(values, xoff=0, yoff=0)
对于大图像,此过程需要很长时间。这就是为什么我想问一下是否有人知道更快的方法。我不太了解python中不同变量的访问速度。或者也许有人知道我可以使用的图书馆。 提前致谢, 马里奥
答案 0 :(得分:5)
你绝对应该使用NumPy。我使用一些相当大的栅格数据集,NumPy通过它们进行烧录。在我的机器上,使用下面的代码,1000 x 1000阵列没有明显的延迟。关于这是如何工作的解释遵循代码。
import numpy as np
from scipy.spatial.distance import cdist
# some starter data
dim = (1000,1000)
values = np.random.randint(0, 10, dim)
# cdist will want 'samples' as a 2-d array
samples = np.array([1, 2, 3]).reshape(-1, 1)
# this could be a one-liner
# 'values' must have the same number of columns as 'samples'
mins = cdist(values.reshape(-1, 1), samples)
outvalues = mins.argmin(axis=1).reshape(dim)
cdist()
计算values
中每个元素与samples
中每个元素的“距离”。这将生成1,000,000 x 3阵列,其中每行n
具有从原始数组中的像素n
到每个样本值[1, 2, 3]
的距离。 argmin(axis=1)
为您提供每行的最小值索引,这是您想要的。快速重塑为您提供了图像所需的矩形格式。
答案 1 :(得分:2)
同意Thomas K:使用PIL,或者写一个C函数并使用例如ctypes,或者至少使用一些numPy matrix operations。 或者在现有代码上使用pypy(JIT编译的代码可以快100倍,在图像代码上)。试试pypy并告诉我们你的速度有多快。
底线:永远不要像cPython中的本地像素一样做事,解释和内存-mgt开销会杀了你。