2016-08-15 11 views
1

Я работаю над изображением 6641x2720, чтобы сгенерировать его изображения функций (характеристики Haralick, такие как контраст, второй момент и т. Д.), С помощью движущегося GLCM (матрицы уровня совпадения уровня). Но навсегда нужно бежать. Код работает нормально, поскольку я тестировал его на более мелких изображениях. Но мне нужно заставить его работать быстрее. Уменьшение размеров до 25% (1661x680) требует 30 минут для запуска. Как я могу заставить его работать быстрее? Вот код:Уменьшить время работы в анализе текстуры с помощью GLCM [Python]

from skimage.feature import greycomatrix, greycoprops 
import matplotlib.pyplot as plt 
import numpy as np 
from PIL import Image 
import time 
start_time = time.time() 
img = Image.open('/home/student/python/test50.jpg').convert('L') 
y=np.asarray(img, dtype=np.uint8) 
#plt.imshow(y, cmap = plt.get_cmap('gray'), vmin = 0, vmax = 255) 
contrast = np.zeros((y.shape[0], y.shape[1]), dtype = float) 

for i in range(0,y.shape[0]): 
    for j in range(0,y.shape[1]): 
     if i < 2 or i > (y.shape[0]-3) or j < 2 or j > (y.shape[1]-3): 
      continue 
     else: 
      s = y[(i-2):(i+3), (j-2):(j+3)] 
      glcm = greycomatrix(s, [1], [0], symmetric = True, normed = True) 
      contrast[i,j] = greycoprops(glcm, 'contrast') 
print("--- %s seconds ---" % (time.time() - start_time)) 
plt.imshow(contrast, cmap = plt.get_cmap('gray'), vmin = 0, vmax = 255) 
+0

Возможно, вам стоит попробовать свести ваши данные в 4 бит [0-16] и не использовать все 256 значений серого. Посмотрите на уровни параметров в http://scikit-image.org/docs/dev/api/skimage.feature.html#skimage.feature.greycomatrix. –

+0

Уменьшить количество ящиков не изменит время вычисления. – FiReTiTi

+0

'greycomatrix' имеет 4 вложенных цикла' for' в своей реализации, что означает, что этот код, вероятно, имеет время выполнения O (n ** 6). Я не уверен, что эту конкретную функцию можно уменьшить, не переписывая функции «greycomatrix» и «greycoprops». – callyalater

ответ

0

Наполните КРНБОМ является линейной операцией: вы просто пройти через все пиксели на изображении/окне, и вы заполнить соответствующие матричный случай. Ваша проблема в том, что вы выполняете операцию для каждого пикселя, а не только для изображения. Таким образом, в вашем случае, если размер изображения - ширина и высота, а размеры окна - NxN, то общая сложность - это ширина x высота x (NxN + FeaturesComplexity), что очень плохо.

Существует гораздо более быстрое решение, но реализовать его сложнее. Цель состоит в том, чтобы уменьшить операции заполнения матрицы. Идея состоит в том, чтобы последовательно работать с форвардным фронтом и обратным фронтом (принцип уже используется для получения быстрых операторов математической морфологии, см. here и here). Когда вы заполняете матрицу для двух последовательных пикселей, вы повторно используете большинство пикселей, на самом деле только те, что слева и справа, различны, поэтому задний и передний фронт соответственно.

Вот иллюстрация для окна КРНБ размеров 3x3:

x1 x2 x3 x4

х5 P1 P2 x6

x7 x8 x9 x10

Когда Окно сосредоточено на p1, вы используете пиксели: x1, x2, x3, x5, p2, x7, x8, x9. Когда окно центрируется на p2, вы используете пиксели: x2, x3, 4, p1, x6, x8, x9, x10. Итак, для p1 вы используете x1, x5 и x7, но вы не используете их для p2, но все остальные пиксели одинаковы.

Идея алгоритма состоит в том, чтобы вычислить матрицу, обычно для p1, но когда вы переходите на p2, вы удаляете задний фронт (x1, x2, x5) и добавляете передний фронт (x4, x6, x10) , Это значительно сокращает время вычисления (линейное, а не квадратичное для операций математической морфологии). Вот алгоритм:

  1. Для каждой строки:
  2. ----- Заполните матрицу (как обычно) для первого пикселя в строке и вы вычислить функции
  3. ----- Для каждого из следующих пикселей:
  4. ----- ----- Добавить передний фронт (новые пиксели в окне)
  5. ----- ----- Удалить задний фронт (в пикселях нет дольше в окне)
  6. ----- ----- Вычислить функции