[PYTHON] Détection d'image de visage similaire utilisant la reconnaissance faciale et le clustering PCA et K-means

introduction

La détection d'images similaires est l'une des fonctions les plus couramment utilisées dans la reconnaissance d'images. Les systèmes de recommandation et de recherche utilisent souvent des dizaines de milliers ou des centaines de milliers d'images. Selon la taille des images et la méthode de comparaison, la recherche d'images similaires parmi des milliers ou des dizaines de milliers nécessite un temps de traitement énorme. Par conséquent, nous allons envisager une méthode pour détecter des images similaires en réduisant la quantité de données et le nombre de comparaisons en utilisant k-means et PCA.

Face Recognition Les fonctionnalités de visage utilisent face_landmark, qui est représentée par un vecteur de 128 dimensions et peut être implémentée dans la bibliothèque à l'URL suivante. https://github.com/ageitgey/face_recognition

Le nombre de dimensions après l'APC a été fixé à 20 tout en observant le taux de cotisation. Après avoir effectué l'ACP et réduit les dimensions, classer en grappes avec K = 10 par k-moyennes. Le plus proche est calculé à partir du centre de gravité de chaque cluster, et seules les images classées dans le cluster avec le centre de gravité le plus proche sont calculées et la distance est calculée pour détecter des images similaires. Il est également efficace pour réduire la capacité de stockage en enregistrant les caractéristiques de l'image sous forme de données réduites par PCA.

En utilisant 1000 images, le clustering par la méthode des k-moyennes permet de comparer 100 fois + 10 fois (comparaison avec le centre de gravité de chaque cluster) en moyenne. De plus, le nombre de dimensions de chaque vecteur a été réduit de 128 à 20 par PCA, de sorte que la quantité de calcul peut être efficacement réduite.

http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html Cette fois, la source d'échantillon utilisant cette image de visage libre est indiquée ci-dessous.

programme


# coding:utf-8
import dlib
from imutils import face_utils
import cv2
import glob
import face_recognition
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from matplotlib import pyplot as plt
import numpy as np

# --------------------------------
# 1.Préparation à la détection des points de repère du visage
# --------------------------------
#Outil de détection de visage d'appel
face_detector = dlib.get_frontal_face_detector()

#Appeler un outil de détection de repère de visage
predictor_path = 'shape_predictor_68_face_landmarks.dat'
face_predictor = dlib.shape_predictor(predictor_path)

images = glob.glob('./faces/*.jpg')
images = sorted(images)[:100]

face_landmarks = []
face_filepaths = []

for filepath in images:
    #Appel de l'image à détecter
    img = face_recognition.load_image_file(filepath)

    face_encodings = face_recognition.face_encodings(img)
    if (len(face_encodings)>0):
        face_filepaths.append(filepath)
        face_landmarks.append(face_encodings[0])

pca = PCA(n_components=20)
pca.fit(face_landmarks)

#Convertir l'ensemble de données en composant principal en fonction du résultat de l'analyse
transformed = pca.fit_transform(face_landmarks)

#Tracer les principaux composants
# plt.subplot(1, 2, 2)
plt.scatter(transformed[:, 0], transformed[:, 1])
plt.title('principal component')
plt.xlabel('pc1')
plt.ylabel('pc2')

#Sortez le taux de cotisation pour chaque dimension de la composante principale
print(pca.explained_variance_ratio_)
print(sum(pca.explained_variance_ratio_))

# print(transformed[0])
# print(len(transformed[0]))

#Démarrer Kmeans
#Nombre de clusters
K = 8
cls = KMeans(n_clusters = 8)
pred = cls.fit_predict(transformed)

#Colorez chaque élément pour chaque étiquette
for i in range(K):
    labels = transformed[pred == i]
    plt.scatter(labels[:, 0], labels[:, 1])

#Centroïde du cluster(Centre de gravité)Dessiner
centers = cls.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], s=100,
            facecolors='none', edgecolors='black')

#Trouvez le centre de gravité le plus proche de vous
min_center_distance = -1
min_center_k = 0

#Trouvez quel centre de gravité est le plus éloigné
max_center_distance = -1
max_center_k = 0

for center_index in range(K):
    distance = np.linalg.norm(transformed[0] - centers[center_index])
    if ( distance < min_center_distance or min_center_distance == -1):
        min_center_distance = distance
        min_center_k = center_index
    if ( distance > max_center_distance or max_center_distance == -1):
        max_center_distance = distance
        max_center_k = center_index

#Afficher les noms d'image des clusters les plus proches et les plus éloignés
print('=========== NEAREST ==============')
for i in range(len(pred)):
    if ( min_center_k == pred[i] ):
        print(face_filepaths[i])
print('=========== FARTHEST ==============')
for i in range(len(pred)):
    if ( max_center_k == pred[i] ):
        print(face_filepaths[i])
print('=========================')

#Afficher le graphique
plt.show()


#* En dessous se trouve une jambe de serpent
#Calculez la distance directe à chaque image
distance = {}
for index in range(len(transformed)):
    distance[face_filepaths[index]] = np.linalg.norm(transformed[0] - transformed[index])

#Trié et affiché par ordre de distance
print(sorted(distance.items(), key=lambda x:x[1]))

Graphique des résultats du clustering

Les traits de l'image, dont le centre de gravité est divisé en grappes par des cercles creux, sont affichés dans différentes couleurs. C'est un peu difficile à comprendre car le graphique à 20 dimensions est tracé en 2 dimensions, mais vous pouvez voir que les principaux composants qui sont proches les uns des autres sont regroupés. image.png

résultat de l'analyse

Image basée sur l'analyse

1.jpg
000001.jpg

Images contenues dans le même cluster

10.jpg 11.jpg 19.jpg 24.jpg
000010.jpg 000011.jpg 000019.jpg 000024.jpg

Image contenue dans le cluster avec le centre de gravité le plus éloigné

12.jpg 37.jpg 51.jpg 60.jpg
000012.jpg 000037.jpg 000051.jpg 000060.jpg

Prise en compte des résultats

Un grand nombre des images divisées dans le même groupe étaient des femmes aux cheveux longs, et beaucoup des images divisées dans le groupe le plus éloigné étaient des hommes aux cheveux courts, donc je pense qu'un regroupement similaire à la sensation humaine était possible. Si vous voulez obtenir une image plus rigoureuse, vous devez calculer la norme directement comme l'image entière sans analyser les composants principaux, mais elle semble être utilisée cette fois pour viser le hasard et réaliser un calcul plus rapide. Il semble bon d'envisager la méthode.

Recommended Posts

Détection d'image de visage similaire utilisant la reconnaissance faciale et le clustering PCA et K-means
Inférence d'image de visage à l'aide de Flask et TensorFlow
Reconnaissance d'image à l'aide de chevaux et de cerfs CNN
Apprentissage automatique: reconnaissance d'image de MNIST à l'aide de PCA et de Gaussian Native Bayes
Détermination des maladies des arbres par reconnaissance d'image à l'aide de CNTK et SVM
Essayez d'utiliser scikit-learn (1) - Clustering K par méthode moyenne
J'ai essayé la reconnaissance faciale avec Face ++
[Traitement d'image] Poo-san est nu par détection de bord en utilisant Python et OpenCV!
Reconnaissance faciale à l'aide de l'analyse des composants principaux
python x tensoflow x reconnaissance de visage d'image
Construction et bases de l'environnement de reconnaissance d'image
AI explicable ~ Clustering k-moyennes et k-médianes explicables ~
Détection de visage à l'aide d'un classificateur en cascade
Reconnaissance d'image des fruits avec VGG16
Détection de visage à partir de plusieurs fichiers image avec openCV, découpez et enregistrez
Reconnaissance faciale à l'aide d'OpenCV (classificateur de caractéristiques de type Haar)
100 traitement du langage knock-97 (en utilisant scicit-learn): clustering k-means
Python: principes de base de la reconnaissance d'image à l'aide de CNN
Hello World et détection de visage avec opencv-python 4.2
Estimation de catégorie à l'aide de l'API de reconnaissance d'image de docomo
Détection de visage Dlib et compteur de clignotements par Python
Python: Application de la reconnaissance d'image à l'aide de CNN
Modèle de reconnaissance d'image utilisant l'apprentissage profond en 2016
Extraire la couleur de l'objet dans l'image avec le clustering Mask R-CNN et K-Means
L'IA peut-elle faire la distinction entre Carlos Gone et M. Bean (reconnaissance faciale à l'aide de repères faciaux)?