2013-12-01 2 views
2

Я пытаюсь вычислить коэффициенты корреляции одного пикселя для всего изображения. я следующий код, который работаетNump вычисляющий corrcoef для больших мультиспектральных изображений

#load picture from serialized data 21 channels, ~500 x ~900 px 
pic=pickle.load(open('hyper.p','rb')) 

#prepare result table 
result=zeros((pic.shape[1],pic.shape[2])) 

#one pixel(10,10) from the image, all the channels 
pixel=pic[:,10,10] 

#for all pixels 
for x in xrange(pic.shape[1]): 
    for y in xrange(pic.shape[2]): 
      #calculate correlation coeficient between one pixel and current pixel 
     miniciurek = corrcoef(pixel,pic[:,x,y]) 
     result[x,y] = miniciurek[1,0] 

imshow(result) 
colorbar() 
show() 

код выше работ, но это занимает значительное количество времени, чтобы закончить, я слышал, что есть лучший способ вычисления значений, способ, который будет делать партию расчет сразу, так что я придумал такое решение:

#flattern the (21,~500,~900) matrix into a (21,500*900) matrix 
orka = pic.reshape((pic.shape[0],pic.shape[1]*pic.shape[2],)) 

#create a matrix full of pixels same as the chosen one 
pur = zeros((pic.shape[0],pic.shape[1]*pic.shape[2])) 
for a in xrange(pic.shape[0]): 
    pur[a,:].fill(krzywa1[a]) 

#at this point I have two (21,~300000) matrixes 
tempResult = corrcoef(pur ,orka ,0) 

я застрял в этот момент, потому что corrcoef пытается выделить (600k, 600k) матрица, которая терпит неудачу. Значения, которые мне нужны, находятся в одной из диагоналей этой огромной матрицы.

  1. Есть ли способ избежать создания таких объемов данных при использовании corrcoef? Нарезание изображения на 1000 пиксельных партий и подача их на corrcoef занимает больше времени, чем просто одиночные пиксели!

  2. Есть ли в python/numpy процедуры пакетного выполнения, которые могут ускорить это?

ответ

0

Я не уверен, как ускорить это, используя функцию corrcoef. Но, если вы знаете, что функция corrcoeff просто вычисляет Pearson's correlation coefficient, легко написать собственный код, чтобы сделать то же самое. Вот функция, которая делает то, что вы хотите:

import numpy as np 

def correlation(pixel, image): 
    c, m, n = image.shape 
    image = image.reshape(c, m * n) 

    pixel_mean = pixel.mean() 
    pixel_std = pixel.std() 
    means = image.mean(0) 
    stds = image.std(0) 

    # calculate the covariance between `pixel` and each image pixel 
    covs = np.dot(pixel - pixel_mean, image - means)/float(c) 

    # calculate Pearson's correlation coefficient 
    corr = covs/(pixel_std * stds) 
    return corr.reshape(m, n) 

# generate a random image to test 
c = 21 
m = 500 
n = 900 
image = np.random.randn(c, m, n) 
corr = correlation(image[:,10,10], image) 

# check an arbitrary point to make sure it works 
assert np.allclose(corr[302, 411], 
        np.corrcoef(image[:,10,10], image[:,302,411])[0,1]) 

Это вычисляет коэффициенты корреляции между одним пикселем и друг с другом пикселя в изображении. Хотя, если ваша конечная цель состоит в том, чтобы вычислить корреляцию между каждым пикселем и каждым другим пикселем на изображении, у вас не хватит памяти (вам потребуется около 1,5 терабайт только для хранения всех коэффициентов, для данного размера изображения 500 x 900).

Смежные вопросы