numpy:基于距离中心的二维像素欧氏距离的一维直方图

numpy:基于距离中心的二维像素欧氏距离的一维直方图,numpy,histogram,multidimensional-array,Numpy,Histogram,Multidimensional Array,我正在使用python,使用scipy、numpy等 我想计算灰度图像强度值的直方图,基于像素到图像质心的距离。以下解决方案可行,但速度非常慢: import matplotlib.pyplot as plt from scipy import ndimage import numpy as np import math # img is a 2-dimensionsl numpy array img = np.random.rand(300, 300) # center of mass of

我正在使用python,使用scipy、numpy等

我想计算灰度图像强度值的直方图,基于像素到图像质心的距离。以下解决方案可行,但速度非常慢:

import matplotlib.pyplot as plt
from scipy import ndimage
import numpy as np
import math

# img is a 2-dimensionsl numpy array
img = np.random.rand(300, 300)
# center of mass of the pixels is easy to get
centerOfMass = np.array(list(ndimage.measurements.center_of_mass(img)))

# declare histogram buckets
histogram = np.zeros(100)

# declare histogram range, which is half the diagonal length of the image, enough in this case.
maxDist = len(img)/math.sqrt(2.0)

# size of the bucket might be less than the width of a pixel, which is fine.
bucketSize = maxDist/len(histogram)

# fill the histogram buckets
for i in range(len(img)):
    for j in range(len(img[i])):
        dist = np.linalg.norm(centerOfMass - np.array([i,j]))
        if(dist/bucketSize < len(histogram)):
            histogram[int(dist/bucketSize)] += img[i, j]

# plot the img array
plt.subplot(121)
imgplot = plt.imshow(img)
imgplot.set_cmap('hot')
plt.colorbar()
plt.draw()

# plot the histogram
plt.subplot(122)
plt.plot(histogram)
plt.draw()

plt.show()
导入matplotlib.pyplot作为plt
从scipy导入ndimage
将numpy作为np导入
输入数学
#img是一个二维的数字阵列
img=np.rand.rand(300300)
#像素的质心很容易得到
质量中心=np.阵列(列表(ndimage.测量值.质量中心(img)))
#声明直方图存储桶
直方图=np.零(100)
#声明直方图范围,即图像对角线长度的一半,在这种情况下就足够了。
maxDist=len(img)/math.sqrt(2.0)
#桶的大小可能小于像素的宽度,这很好。
bucketSize=maxDist/len(直方图)
#填满直方图桶
对于范围内的i(len(img)):
对于范围内的j(len(img[i]):
dist=np.linalg.norm(质量中心-np.array([i,j]))
如果(dist/bucketSize

正如我之前所说的,这是可行的,但速度非常慢,因为在numpy中不应该以这种方式对数组进行双循环。有没有更有效的方法做同样的事情?我假设我需要对所有数组元素应用一些函数,但我也需要索引坐标。我该怎么做?目前,1kx1k图像需要几秒钟的时间,速度慢得离谱。

所有numpy binning函数(
bincount
historogram2d
…都有一个
weights
关键字参数,你可以用它来做一些非常奇怪的事情,比如你的事情。我会这样做:

rows, cols = 300, 300
img = np.random.rand(rows, cols)

# calculate center of mass position
row_com = np.sum(np.arange(rows)[:, None] * img) / np.sum(img)
col_com = np.sum(np.arange(cols) * img) / np.sum(img)

# create array of distances to center of mass
dist = np.sqrt(((np.arange(rows) - row_com)**2)[:, None] +
               (np.arange(cols) - col_com)**2)

# build histogram, with intensities as weights
bins = 100
hist, edges = np.histogram(dist, bins=bins, weights=img)

# to reproduce your exact results, you must specify the bin edges
bins = np.linspace(0, len(img)/math.sqrt(2.0), 101)
hist2, edges2 = np.histogram(dist, bins=bins, weights=img)

尚未对这两种方法进行计时,但从从终端运行这两种方法时的延迟来看,速度明显更快。

比我的答案好得多。有趣的是,但回想起来并不奇怪,np.histogram可以使用多维数组。@Ophion它可以使用任何方法,但在处理之前它总是变平。谢谢你在很多情况下,我一直在玩一系列的距离游戏,因为这似乎是一条路要走,但我无法让它工作。