Python中的聚类- 图像聚类

3

我想使用K均值或其他算法(需要建议)对图像进行聚类。

问题是这样的- 我想将图像分成3个群组(自然,日落,水)。我使用os.listdir()加载了所有的图像,然后将所有图像转换为数组(RGB),并创建了一个包含三列的数据框-ID、Image_array、Label。

现在,当我使用K均值聚类,并提供n_clusters = 3时,它显示以下错误:

from sklearn.cluster import KMeans kmeans = KMeans(n_clusters = 3).fit(img_array) ERROR = Found array with dim 4. Estimator expected <= 2.

现在,我需要您在此聚类问题上的帮助。我创建的数据框如下所示:

img_array = []

path = "C://Users/shivam/Desktop/freelancer/p22/data/green_nature/"
for f in os.listdir('.'):
    if f.endswith('.jpg'):
        img = Image.open(f)
        data = np.asarray(img, dtype='uint8')
        img_array.append(data)


df = pd.DataFrame({'image_arrays':img_array})
df['id'] = range(1, len(df) + 1)
2个回答

0

正如你所说,k-means希望每个输入都有一个向量,而你提供的是每个图像的3D数组。解决这样的问题(需要一些创意)最简单的方法是设计一组特征,这些特征对于你拥有的类别具有区分性。

由于在这种情况下,你希望分类自然(大量绿色),水(大量蓝色)和日落(大量红/黄/粉色?),因此可以使用总体或平均绿色、蓝色和红色值。要检查你选择的特征是否具有区分性,可以绘制直方图。

从你的4D(图像x宽度x高度x颜色)数组转换为2D(图像x平均颜色)数组,你需要在颜色、高度和宽度维度上取np.mean。最终,你应该有一个(图像x 3(颜色))数组。


np.mean(image_arrays,axis=2)是什么意思?请参考https://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html。 - TheLaurens
我也尝试了同样的事情,但是有些问题?数组是四维的,使用np.mean(axis =2),我们去掉了第四个维度,然后再次使用axis = 0。我们又切掉了另一个维度。现在它是一个二维数组,可以被K MEANS接受,但是我很困惑,这样做对吗?如果我们使用ndarray.flatten把它削成一个一维数组并且得到平均值呢? - user7759009
如果你选择后者,你会得到颜色的平均值,这可能会导致很多数据丢失。 - TheLaurens
嗨,现在它是一个二维数组,但我有300个类。在分别应用轴=0、2之后。但我的数据集只有24个实例,我犯了错。 - user7759009
你应该在轴1(宽度)和2(高度)上进行平均,因为这些是你想要消除的维度。 - TheLaurens
显示剩余2条评论

0
这是因为您传递了一个4维数组,而期望的是2维数组。'img_array.shape' 应该像这样(n_samples, n_features)。 您需要使用特征提取算法。
这可以通过scikit-image模块完成。 您需要将图像转换为灰度格式。 代码:
import skimage.feature as feature
img_converted = []
for i in range(len(img_array)):
    img_converted.append(feature.hog(img_array[i]))
model.fit(np.array(img_converted))

文档:http://scikit-image.org/docs/dev/api/skimage.feature.html#hog


我需要更多的解释,你能提供你的代码给我吗? 此时此刻,我正在考虑如何将数组转换为另一个二维数组,该数组每行都有平均值和标准差,以便Kmeans可以获取。 - user7759009
我也在尝试同样的事情,但是有一些问题。数组是4D的,使用了np.mean(axis=2),我们切掉了第四个维度,现在我又使用了axis=0。我们又切掉了另一个维度。现在它是一个2D数组,可以被K MEANS接受,但是我很困惑,这样做对吗?如果我们使用ndarray.flatten将其切成1D数组并获取平均值呢? - user7759009
我无法使用那个,所以我将img_array转换为2D数组,通过在axis = 0和axis = 2处获取np.mean。现在我的类别有300个。但是在应用axis = 0,2之后,我的数据集只有24个实例,我犯了什么错误? - user7759009
img_array.shape = (24, 300, 400, 3)img_array的形状为(24, 300, 400, 3)。 - user7759009

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接