我正在尝试计算一个像素与整个图像的相关系数。我有下面的代码,工作
#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)
我在这一点上被卡住了,因为corrcoeff试图分配一个(600k,600k)矩阵,但失败了。我需要的值在这个巨大矩阵的一条对角线上。
在使用corrcoeffe时,有什么方法可以避免生成如此大量的数据吗?将图像分割成1000个像素批次并将其输入corrcove比仅使用单个像素需要更长的时间!
python/numpy是否有任何批处理执行例程可以加快速度?
我不知道如何使用corrcove函数来加快速度。但是,如果你知道corrcoeff函数只是计算Pearson的相关系数,那么很容易编写自己的代码来做同样的事情。这里有一个功能可以满足您的需求:
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])
这计算图像中的一个像素和另一个像素之间的相关系数。尽管如此,如果你的最终目标是计算图像中每个像素和其他像素之间的相关性,你就会耗尽内存(对于给定的图像大小500 x 900,你只需要大约1.5 TB来存储所有系数)。