5

我正在尝试使用 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中不同变量的访问速度了解不多。或者也许有人知道我可以使用的库。在此先感谢,马里奥

4

2 回答 2

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计算从 in 中的每个元素到 中的每个元素的“距离” samples。这会生成一个 1,000,000 x 3 数组,其中每一行都有从原始数组中的像素到每个样本值n的距离。为您提供每行最小值的索引,这就是您想要的。快速重塑可为您提供您期望的图像矩形格式。n[1, 2, 3]argmin(axis=1)

于 2011-08-15T05:14:16.933 回答
2

同意 Thomas K:使用PIL,或者编写一个 C 函数并使用例如 ctypes 包装它,或者至少使用一些numPy 矩阵操作。或者在现有代码上使用 pypy(在图像代码上,JIT 编译的代码可以快 100 倍)。试试 pypy 并告诉我们你得到了什么加速。

底线:永远不要在 cPython 中原生地做这样的事情,解释和内存管理开销会杀死你。

于 2011-06-30T20:36:34.463 回答