Python 带遮罩过滤器的颜色分类的K-均值:值错误:无法将13498大小的数组重塑为形状(3)

Python 带遮罩过滤器的颜色分类的K-均值:值错误:无法将13498大小的数组重塑为形状(3),python,opencv,k-means,Python,Opencv,K Means,我正在尝试使用KMeans对图像中对象的颜色进行分类。首先,我使用了一个遮罩来减去图像的背景,以便将对象从背景中分离出来。因此,我正在处理一个纯黑色背景的图像,即rgb(0,0,0),对象孤立地位于该黑色空间内。现在我想对图像中对象的颜色执行KMeans,而不将背景输入算法,因为我不希望背景包含在集群中 我试图过滤掉黑色像素,然后重塑阵列,以便将其提供给分类器 # reshape the image to be a list of pixels image = image[image

我正在尝试使用KMeans对图像中对象的颜色进行分类。首先,我使用了一个遮罩来减去图像的背景,以便将对象从背景中分离出来。因此,我正在处理一个纯黑色背景的图像,即rgb(0,0,0),对象孤立地位于该黑色空间内。现在我想对图像中对象的颜色执行KMeans,而不将背景输入算法,因为我不希望背景包含在集群中

我试图过滤掉黑色像素,然后重塑阵列,以便将其提供给分类器

 # reshape the image to be a list of pixels
    image = image[image != 0]
    image = np.reshape(image, (-1,3))

    # cluster the pixel intensities
    clt = KMeans(n_clusters = 3, n_jobs=1,random_state=42)
    clt.fit(image)
虽然这适用于某些图像,但我会收到其他一些图像的错误消息,如下所示:

ValueError:无法将大小为13498的数组重塑为形状(3)

是否有任何方法可以在过滤后动态调整数组的大小,以使其适合形状3


我使用的是PythonV3,图像是使用OpenCV2加载的。您的问题是,您首先查找的是所有非零值,而不是非黑色像素。。。我想这是你的最终目标。举一个简单的问题示例,假设我们得到3个非零值像素,即9个值:

import numpy as np

a = np.array([1,2,3,4,5,6,7,8,9])
a = np.reshape(a, (-1,3))
这可能不会给您带来错误,但如果对于像素,其中一个通道的值实际上为0,会发生什么情况?那么你就少了一个值。例如,假设它只针对一个值,那么您将只得到8个值:

import numpy as np

a = np.array([1,2,3,4,5,6,7,8])
a = np.reshape(a, (-1,3)) #Error
它没有足够的值来执行重塑。。。如果在不同像素的一个通道中有更多的像素具有此0值,则问题可能会变得更严重。。。如果数量是3的倍数,则函数不会给出错误,但像素颜色将全部错误:(

您也可以尝试错误中的数字:
13498/3=4499.333
这意味着至少有一个值为0(实际上至少为2)

我不是numpy的最佳选择,但解决您问题的有效方法可能是:

# create the indices that have at least one channel of the pixel different than 0
indToSelect = np.any(image != 0, keepdims=True, axis=2)[:,:,0] # used [:,:,0] because numpy returns an array of shape (rows, cols, 1)
# get the 3 channel values of the selected values above
forKmeans = image[indToSelect, :]
这已经提供了一个BGR像素阵列,其形状为(点,3),因此无需重塑。我希望这对您有所帮助