我偶然发现了这件事,但无法理解发生的事情。我正在对图像进行K-means聚类分配,并尝试对代码进行矢量化以使其尽可能快地运行。我想出了以下代码:
image_values =np.array( [[[ 0.36302522 0.51708686 0.20952381]
[ 0.46330538 0.69915968 0.2140056 ]
[ 0.7904762 0.93837535 0.27002802]
[ 0.78375351 0.89187676 0.24201682]
[ 0.57871151 0.79775912 0.24593839]
[ 0.2896359 0.39103645 0.64481789]
[ 0.23809525 0.30924368 0.64257705]]
[[ 0.36302522 0.51708686 0.20952381]
[ 0.46330538 0.69915968 0.2140056 ]
[ 0.7904762 0.93837535 0.27002802]
[ 0.78375351 0.89187676 0.24201682]
[ 0.57871151 0.79775912 0.24593839]
[ 0.2896359 0.39103645 0.64481789]
[ 0.23809525 0.30924368 0.64257705]]
[[ 0.36302522 0.51708686 0.20952381]
[ 0.46330538 0.69915968 0.2140056 ]
[ 0.7904762 0.93837535 0.27002802]
[ 0.78375351 0.89187676 0.24201682]
[ 0.57871151 0.79775912 0.24593839]
[ 0.2896359 0.39103645 0.64481789]
[ 0.23809525 0.30924368 0.64257705]]])
means = np.array([[0.909,0.839,0.6509],[0.813,0.808,0.694],[0.331,0.407,0.597]]) #random centroids
err = 1
while err > .01:
J = [np.sum((image_values-avg)**2, axis = 2) for avg in means]
K = np.argmin(J, axis = 0)
old_means = means
means = np.array([np.mean(image_values[K==i], axis ==True) for i in range(len(means))])
print means
err = abs(sum(old_means)-sum(means))
print err
在每个新的平均值计算中,我使用我的K数组来选择每个平均值计算中应包含哪些像素值,但我无法让轴达成一致。我实际上做了一个错字,而不是轴= 3,我键入轴== 3,它工作!我尝试了一堆不同的数字,发现数字是什么并不重要,结果是一样的。我尝试了一堆数字和布尔运算器,他们没有工作。我已经阅读了文档,但我无法理解。
numpy在其中一个数组函数的axis参数中获取逻辑if时会做什么?
谢谢!
答案 0 :(得分:1)
我不完全确定我完全明白你要做什么。这就是我的假设;您有一个具有RGB值的单个图像,并且您希望对此图像中的像素进行聚类。因此,每个质心将分别为每个颜色通道定义一个值。我假设means
矩阵中的每一行都是一个质心,列是RGB值。
在你的方法中,我认为你减去质心的方式可能有误。您需要为每个质心创建一个距离矩阵(此时您没有正确地减去每个颜色通道)。
这是一个主张。请注意,对于给定的示例数据,您将遇到NaN
错误,因为并非所有质心都具有最接近它们的像素。您可能还需要根据需要调整停止标准。
err = 1
while err > 0.1:
# There are three centroids. We would like to compute the
# distance for each pixel to each centroid. Here, the image
# is thus replicated three times.
dist = np.tile(image_values, (3,1,1,1))
# The 2D matrix needs to be reshaped to fit the dimensions of
# the dist matrix. With the new shape, the matrix can directly
# be subtracted.
means2 = means.reshape(3,3,1,1)
# Subtract each respective RGB value of the centroid for
# each "replica" of the image
J = np.power(dist - means2, 2)
# Sum the r,g,b channels together to get the total distance for a pixel
J = J.sum(axis=1)
# Check for which cluster the pixel is closest
K = np.argmin(J, axis=0)
# I couldn't think of a better way than this loop
newMeans = np.zeros((3,3))
for i in range(means.shape[0]): # do each centroid
# In axis 1 there are pixels which we would like to
# average for each color channel (axis 0 are the RGB channels)
newMeans[i,:] = image_values[:,K==i].mean(axis=1)
err = np.power(means - newMeans, 2).sum()
means = newMeans