Clustering images by hierarchical clustering

Clustering images by hierarchical clustering#

Mahmood Amintoosi, Fall 2024

Computer Science Dept, Ferdowsi University of Mashhad

# Auto-setup when running on Google Colab
import os
if 'google.colab' in str(get_ipython()) and not os.path.exists('/content/mfds'):
    !git clone https://github.com/fum-cs/mfds.git
    %cd mfds/notebooks
# وارد کردن کتابخانه های مورد نیاز
import os
import numpy as np
from PIL import Image
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from skimage.color import rgb2hsv
from skimage.color import rgb2lab
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage

# تعریف پوشه ای که تصاویر jpg در آن قرار دارند
folder = "images"

# خواندن تصاویر و تبدیل آنها به آرایه های NumPy
images = []
for filename in os.listdir(folder):
    if filename.endswith(".jpg"):
        img = Image.open(os.path.join(folder, filename))
        img = np.array(img)
        images.append(img)

# تعداد تصاویر
n = len(images)

# محاسبه میانگین شدت رنگ پیکسلهای هر تصویر
means = []
for img in images:
    # img = rgb2hsv(img)
    img = rgb2lab(img)
    mean = np.mean(img, axis=(0, 1)) # میانگین بر اساس محورهای ارتفاع و عرض
    means.append(mean)

# تبدیل لیست میانگینها به آرایه NumPy
means = np.array(means)

# خوشهبندی بردارهای میانگین با الگوریتم k-means
k = 3 # تعداد خوشه ها 
# kmeans = KMeans(n_clusters=k, random_state=42)
# kmeans.fit(means)
# labels = kmeans.labels_ # برچسب خوشه ها
clustering = AgglomerativeClustering(linkage='ward', n_clusters=k)  
labels = clustering.fit_predict(means)
labels
array([0, 0, 0, 1, 1, 1, 2, 2, 2], dtype=int64)
# نمایش تصاویر هر خوشه
for i in range(k):
    # انتخاب تصاویری که به خوشه i تعلق دارند
    cluster = [images[j] for j in range(n) if labels[j] == i]
    # تعداد تصاویر در خوشه i
    m = len(cluster)
    # تعیین اندازه شکل برای نمایش تصاویر
    plt.figure(figsize=(10, 3))
    # حلقه برای نمایش تصاویر
    for j in range(m):
        # ایجاد یک زیر شکل برای هر تصویر
        plt.subplot(1, m, j + 1)
        # حذف محورها
        plt.axis("off")
        # نمایش تصویر
        plt.imshow(cluster[j])
    # نمایش عنوان شکل
    plt.suptitle(f"Cluster {i}")
    # نمایش شکل
    plt.show()
../_images/c8608243b78a2290123dab6b3fae7ef0a4b06a8c1a596c97a0baef7a085b5bcd.png ../_images/97ce83a4d171ef17e06ba7daa40e1d2a02179ca361a386c7a488db26ee0ec121.png ../_images/bb1318e720b4e587628c3975db18160b58969017801e874fd923d7e4c38fa994.png
linkage_matrix = linkage(means, method='ward')  # Create linkage matrix
linkage_matrix
array([[  3.        ,   5.        ,  11.38215326,   2.        ],
       [  6.        ,   7.        ,  14.68492426,   2.        ],
       [  1.        ,   2.        ,  15.82979712,   2.        ],
       [  8.        ,  10.        ,  24.22373583,   3.        ],
       [  4.        ,   9.        ,  27.95633024,   3.        ],
       [  0.        ,  11.        ,  30.62255948,   3.        ],
       [ 12.        ,  14.        ,  57.55943682,   6.        ],
       [ 13.        ,  15.        , 107.55176707,   9.        ]])
from scipy.cluster.hierarchy import leaves_list

linkage_matrix = linkage(means, method='ward')  # Create linkage matrix
leaf_order = leaves_list(linkage_matrix)
leaf_order
array([4, 3, 5, 8, 6, 7, 0, 1, 2], dtype=int32)
plt.figure(figsize=(7, 3))
dendrogram(linkage_matrix, labels=range(len(means))) 
plt.show()
for j in range(n):
    # ایجاد یک زیر شکل برای هر تصویر
    plt.subplot(1, n, j + 1)
    # حذف محورها
    plt.axis("off")
    # نمایش تصویر
    plt.imshow(images[leaf_order[j]])

plt.tight_layout()
plt.show()
../_images/8ce3a55073a29694209c9903585c6263634dd44251650581a6f05b2a94aedf0c.png ../_images/48651d5ec4a5592c8bc6ecaf668b8db8d84f7709d7d0fb0bbe492c47a0bdcfb6.png