python - 通过在 python 中的相似性进行图像聚类

标签 python machine-learning computer-vision cluster-analysis

我有一组照片,我想区分相似照片的簇。我应该使用图像的哪些特征和哪种算法来解决我的任务?

最佳答案

我遇到了同样的问题,我想出了这个解决方案:

  1. 使用 Keras 导入预训练模型(此处为 VGG16)
  2. 提取每张图片的特征
  3. kmeans
  4. 复制带簇标签导出

这是我的代码,部分原因是 this post .

from keras.preprocessing import image
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input
import numpy as np
from sklearn.cluster import KMeans
import os, shutil, glob, os.path
from PIL import Image as pil_image
image.LOAD_TRUNCATED_IMAGES = True 
model = VGG16(weights='imagenet', include_top=False)

# Variables
imdir = 'C:/indir/'
targetdir = "C:/outdir/"
number_clusters = 3

# Loop over files and get features
filelist = glob.glob(os.path.join(imdir, '*.jpg'))
filelist.sort()
featurelist = []
for i, imagepath in enumerate(filelist):
    print("    Status: %s / %s" %(i, len(filelist)), end="\r")
    img = image.load_img(imagepath, target_size=(224, 224))
    img_data = image.img_to_array(img)
    img_data = np.expand_dims(img_data, axis=0)
    img_data = preprocess_input(img_data)
    features = np.array(model.predict(img_data))
    featurelist.append(features.flatten())

# Clustering
kmeans = KMeans(n_clusters=number_clusters, random_state=0).fit(np.array(featurelist))

# Copy images renamed by cluster 
# Check if target dir exists
try:
    os.makedirs(targetdir)
except OSError:
    pass
# Copy with cluster name
print("\n")
for i, m in enumerate(kmeans.labels_):
    print("    Copy: %s / %s" %(i, len(kmeans.labels_)), end="\r")
    shutil.copy(filelist[i], targetdir + str(m) + "_" + str(i) + ".jpg")

02/2022 更新:

在某些情况下(例如未知数量的集群)使用 Affinity Propagation可能是比 kmeans 更好的选择。在这种情况下,将 kmeans 替换为:

from sklearn.cluster import AffinityPropagation
affprop = AffinityPropagation(affinity="euclidean", damping=0.5).fit(np.array(featurelist))

并遍历 affprop.labels_ 以访问结果。

关于python - 通过在 python 中的相似性进行图像聚类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39123421/

相关文章:

python - (Python 3) 输出问题

machine-learning - Pyspark 中的过采样或 SMOTE

python - scikit-learn 中的逻辑回归特征值归一化

search - 图割和图搜索有什么区别吗?

python - 使用 % 和//求除数

python - 使用 git 跟踪对 dropbox 的更改?

opencv - 多个单 channel 矩阵转换为单个多 channel 矩阵

python - 在Jupyter Notebook中第二次运行后无法调用'numpy.ndarray'对象

Python:垃圾收集器行为与 ctypes

machine-learning - 在 weka 中找不到 libsvm 类