Алгоритм минимального расстояния с использованием GDAL и Python - PullRequest
5 голосов
/ 06 мая 2011

Я пытаюсь реализовать алгоритм минимального расстояния для классификации изображений с использованием 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.Или, может быть, кто-то знает библиотеку, которую я мог бы использовать.Заранее спасибо, Марио

Ответы [ 2 ]

5 голосов
/ 15 августа 2011

Вы обязательно должны использовать 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)

<a href="http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html" rel="noreferrer">cdist()</a> вычисляет «расстояние» от каждого элемента в values до каждого из элементов в samples.Это создает массив 1,000,000 x 3, где каждая строка n имеет расстояние от пикселя n в исходном массиве до каждого из значений выборки [1, 2, 3].argmin(axis=1) дает вам индекс минимального значения в каждой строке, что вам и нужно.Быстрое изменение формы дает вам прямоугольный формат, который вы ожидаете для изображения.

2 голосов
/ 01 июля 2011

Согласитесь с Томасом К: используйте PIL , или же напишите C-функцию и оберните ее, например, используя. ctypes или, по крайней мере, использовать некоторые матричные операции numPy . Или используйте pypy в вашем существующем коде (JIT-скомпилированный код может быть в 100 раз быстрее, в коде изображения). Попробуйте pypy и расскажите нам, какое ускорение вы получили.

Итог: никогда не делайте вещи попиксельно, как это изначально в cPython, интерпретация и накладные расходы на память убьют вас.

...