Le regroupement de visages rassemble les images contenant des visages similaires au sein d'un jeu de données. Chaque cluster représente une personne, ce qui vous permet de retrouver toutes les images d'une personne spécifique à partir d'un seul cluster.
Cas d'utilisation courants :
Albums photo cloud -- Organisez automatiquement les photos par personne pour générer des albums personnalisés.
Surveillance domestique -- Le regroupement de visages enregistre les visages des membres de la famille. Lorsqu'un visage inconnu apparaît, le processus échoue et envoie une alerte. Cela vous aide à identifier et gérer les personnes et événements dangereux dès que possible, garantissant ainsi la sécurité de vos proches.
Gestion de la clientèle dans le commerce de détail -- Dédupliquez les images clients pour obtenir des comptages de trafic précis, puis analysez le comportement d'achat pour un marketing ciblé.
Fonctionnement
Le regroupement de visages suit un flux de travail API en trois étapes :
1. Index images CreateBinding, IndexFileMeta, or BatchIndexFileMeta
|
v
2. Cluster faces CreateFigureClusteringTask
|
v
3. Query results QueryFigureClusters --> SimpleQuery (images per cluster)
Indexez les images dans un dataset. Utilisez CreateBinding pour une liaison automatique, ou IndexFileMeta / BatchIndexFileMeta pour une indexation manuelle. Créez le dataset avec CreateDataset.
Exécutez le regroupement de visages. Appelez CreateFigureClusteringTask pour regrouper les visages du dataset. Cette opération est incrémentale : elle ne traite que les nouvelles images depuis la dernière exécution.
Interrogez les clusters et les images. Utilisez QueryFigureClusters pour lister tous les clusters, puis utilisez SimpleQuery pour récupérer toutes les images d'un cluster spécifique.
Prérequis
Avant de commencer, assurez-vous que :
Les images sont indexées dans un dataset via CreateBinding, IndexFileMeta ou BatchIndexFileMeta
Le dataset contient au moins 3 images de la même personne
Au moins 3 de ces images répondent aux exigences de haute définition des visages listées ci-dessous
Exigences pour les visages haute définition
| Critère | Seuil |
|---|---|
| Zone du visage | Supérieure à 75 x 75 pixels |
| HeadPose | Valeur absolue de chaque élément (Pitch, Roll, Yaw) inférieure à 30 |
| FaceQuality | Supérieure à 0,8 |
Appelez GetFileMeta pour vérifier l'angle et la qualité des visages pour les images indexées.
Une fois un cluster créé, les visages ne répondant pas à ces seuils peuvent toujours être ajoutés au même cluster. Pour plus de détails, consultez la rubrique FAQ sur la gestion des images.
Créer une tâche de regroupement de visages
Appelez CreateFigureClusteringTask pour regrouper les visages parmi les images indexées dans un dataset. Cette opération génère uniquement des clusters ; elle ne modifie pas les images originales.
Les informations de tâche sont conservées pendant 7 jours après le démarrage de la tâche. Passé ce délai, les informations de tâche ne sont plus disponibles. Utilisez l'une des méthodes suivantes pour récupérer les résultats de la tâche :
Abonnez-vous à une file d'attente Simple Message Queue (anciennement MNS) dans la même région que le projet IMM.
Créez une instance ApsaraMQ for RocketMQ 4,0 avec un topic et un groupe dans la même région.
Utilisez EventBridge dans la même région pour recevoir les notifications de tâche. Pour les détails sur le format des messages, consultez la rubrique Exemples de messages asynchrones.
Exemple de requête
{
"ProjectName": "test-project",
"DatasetName": "test-dataset"
}
Exemple de réponse
{
"TaskId": "CreateFigureClusteringTask-ba5784b8-f61e-485d-8ea0-****",
"RequestId": "42F4F8FD-006D-0EF0-8F2A-****",
"EventId": "140-1L5dh6eSUErqdxV1ZvJ****"
}
Une réponse réussie inclut un TaskId confirmant la création de la tâche de regroupement.
Exemple de code (Python)
Interroger les clusters de visages
Une fois le regroupement terminé, appelez QueryFigureClusters pour lister tous les clusters d'un dataset. La réponse inclut les métadonnées suivantes pour chaque cluster :
| Champ | Description |
|---|---|
ObjectId |
ID du cluster |
FaceCount |
Nombre de visages dans le cluster |
ImageCount |
Nombre d'images dans le cluster |
Gender |
Genre estimé |
AverageAge, MinAge, MaxAge |
Statistiques d'âge |
Cover |
Image de couverture avec attributs détaillés du visage |
Exemple de requête
{
"ProjectName": "test-project",
"DatasetName": "test-dataset"
}
Exemple de réponse
{
"FigureClusters": [
{
"AverageAge": 27.125,
"Cover": {
"Addresses": [],
"AudioCovers": [],
"AudioStreams": [],
"CroppingSuggestions": [],
"Figures": [
{
"Attractive": 0.9980000257492065,
"Beard": "none",
"BeardConfidence": 0.9959999918937683,
"Boundary": {
"Height": 270,
"Left": 573,
"Top": 104,
"Width": 202
},
"FaceQuality": 1.0,
"FigureId": "d7365ab8-1378-4bec-83cb-eccad8d11e0b",
"FigureType": "face",
"Glasses": "none",
"GlassesConfidence": 0.9990000128746033,
"Hat": "none",
"HatConfidence": 1.0,
"HeadPose": {
"Pitch": -0.7369999885559082,
"Roll": 2.5399999618530273,
"Yaw": 9.138999938964844
},
"Mask": "none",
"MaskConfidence": 0.7269999980926514,
"Mouth": "open",
"MouthConfidence": 0.9959999918937683,
"Sharpness": 1.0
}
],
"ImageHeight": 683,
"ImageWidth": 1024,
"Labels": [],
"OCRContents": [],
"ObjectId": "170ffdeb36cec846f4214c78a0f3a0d4b7e37d0305370216ae780f7b8c72f871",
"Subtitles": [],
"URI": "oss://bucket1/photos/2.jpg",
"VideoStreams": []
},
"CreateTime": "2022-07-12T16:41:19.336825716+08:00",
"DatasetName": "dataset1",
"FaceCount": 16,
"Gender": "female",
"ImageCount": 16,
"MaxAge": 30.0,
"MinAge": 23.0,
"ObjectId": "Cluster-7bdbcedb-bd79-42e7-a1e2-b29a48532bd6",
"ObjectType": "figure-cluster",
"OwnerId": "*****",
"ProjectName": "test-project",
"UpdateTime": "2022-09-19T17:08:59.374781532+08:00",
"VideoCount": 0
},
{
"AverageAge": 24.200000762939453,
"Cover": {
"Addresses": [],
"AudioCovers": [],
"AudioStreams": [],
"CroppingSuggestions": [],
"Figures": [
{
"Attractive": 0.9990000128746033,
"Beard": "none",
"BeardConfidence": 0.9990000128746033,
"Boundary": {
"Height": 266,
"Left": 301,
"Top": 218,
"Width": 196
},
"FaceQuality": 0.8859999775886536,
"FigureId": "f58bbdce-f3d1-4674-be6b-43d4b47c08e1",
"FigureType": "face",
"Glasses": "none",
"GlassesConfidence": 1.0,
"Hat": "none",
"HatConfidence": 1.0,
"HeadPose": {
"Pitch": 13.963000297546387,
"Roll": -12.21399974822998,
"Yaw": -6.2210001945495605
},
"Mask": "none",
"MaskConfidence": 0.7490000128746033,
"Mouth": "open",
"MouthConfidence": 0.9940000176429749,
"Sharpness": 1.0
}
],
"ImageHeight": 1024,
"ImageWidth": 683,
"Labels": [],
"OCRContents": [],
"ObjectId": "b9c80e51aa95072413e2a0a6e5262644bc3cba14a4754f54f3fa9850c4d244f1",
"Subtitles": [],
"URI": "oss://bucket1/photos/11.jpg",
"VideoStreams": []
},
"CreateTime": "2022-09-19T17:08:59.374932448+08:00",
"DatasetName": "test-dataset",
"FaceCount": 5,
"Gender": "female",
"ImageCount": 5,
"MaxAge": 26.0,
"MinAge": 22.0,
"ObjectId": "Cluster-856be781-bf5a-46d7-8494-8d7c44f5e282",
"ObjectType": "figure-cluster",
"OwnerId": "*****",
"ProjectName": "test-project",
"UpdateTime": "2022-09-19T17:08:59.374932448+08:00",
"VideoCount": 0
}
],
"NextToken": "",
"TotalCount": 2,
"RequestId": "42B3DD92-FE0D-09B7-B582-*****"
}
Dans cet exemple, le dataset contient 2 clusters. Le cluster Cluster-7bdbcedb-bd79-42e7-a1e2-b29a48532bd6 contient 16 images, et le cluster Cluster-856be781-bf5a-46d7-8494-8d7c44f5e282 contient 5 images.
Exemple de code (Python)
Interroger les images d'un cluster
Après avoir récupéré les informations du cluster, appelez SimpleQuery avec l'ID du cluster pour lister toutes les images de ce cluster. L'exemple suivant récupère les images du cluster Cluster-7bdbcedb-bd79-42e7-a1e2-b29a48532bd6.
Exemple de requête
{
"ProjectName": "test-project",
"DatasetName": "test-dataset",
"Query": "{\"Field\": \"Figures.FigureClusterId\", \"Operation\": \"eq\", \"Value\": \"Cluster-7bdbcedb-bd79-42e7-a1e2-b29a48532bd6\"}",
"MaxResults": 100
}
Exemple de réponse
Le cluster contient de nombreuses images. L'exemple suivant montre les données d'une seule image.
{
"Aggregations": [],
"Files": [
{
"Addresses": [],
"AudioCovers": [],
"AudioStreams": [],
"ContentMd5": "ViAbCBHAZgNU4zvs5****==",
"ContentType": "image/jpeg",
"CreateTime": "2022-07-12T15:57:47.792615815+08:00",
"CroppingSuggestions": [],
"DatasetName": "test-dataset",
"ETag": "\"56201B0811C0660354E33BECE4C****\"",
"EXIF": "****",
"Figures": [
{
"FaceQuality": 1.0,
"FigureClusterId": "Cluster-7bdbcedb-bd79-42e7-a1e2-b29a48532bd6",
"FigureConfidence": 1.0,
"FigureId": "cd9139bf-f339-4ec2-b5fd-****",
"FigureType": "face",
"Glasses": "none",
"GlassesConfidence": 0.9990000128746033,
"Hat": "none",
"HatConfidence": 1.0,
"HeadPose": {
"Pitch": -0.8999999761581421,
"Roll": 1.1660000085830688,
"Yaw": 7.932000160217285
},
"Mask": "none",
"MaskConfidence": 0.6830000281333923,
"Mouth": "close",
"MouthConfidence": 0.7879999876022339,
"Sharpness": 1.0
}
],
"FileHash": "\"56201B0811C0660354E33BECE****\"",
"FileModifiedTime": "2022-07-12T15:56:41+08:00",
"Filename": "3.jpg",
"ImageHeight": 1024,
"ImageScore": {
"OverallQualityScore": 0.7490000128746033
},
"ImageWidth": 683,
"Labels": [
{
"CentricScore": 0.8349999785423279,
"LabelConfidence": 1.0,
"LabelLevel": 2,
"LabelName": "\u7167\u7247\u62cd\u6444",
"Language": "zh-Hans",
"ParentLabelName": "\u827a\u672f\u54c1"
}
],
"MediaType": "image",
"OCRContents": [],
"OSSCRC64": "3400224321778591044",
"OSSObjectType": "Normal",
"OSSStorageClass": "Standard",
"OSSTaggingCount": 0,
"ObjectACL": "default",
"ObjectId": "d132a61122c659f6fc1b42ecee1662aff358c7f1720027bead225****",
"ObjectType": "file",
"Orientation": 1,
"OwnerId": "****",
"ProduceTime": "2014-02-21T00:03:36+08:00",
"ProjectName": "test-project",
"Size": 187674,
"Subtitles": [],
"URI": "oss://bucket1/1.jpg",
"UpdateTime": "2022-07-12T16:41:19.336736388+08:00",
"VideoStreams": []
}
],
"NextToken": "",
"RequestId": "84E4D242-8D15-0312-B976-****"
}
Ce résultat indique que le cluster inclut une image située à l'adresse oss://bucket1/1.jpg.
Exemple de code (Python)
Bonnes pratiques
Choisir une fréquence de regroupement
CreateFigureClusteringTask est incrémental : il n'est pas nécessaire de l'appeler après chaque indexation d'image. Deux approches recommandées :
| Approche | Fonctionnement | Quand l'utiliser |
|---|---|---|
| Interrogation planifiée | Appelez CreateFigureClusteringTask sur chaque dataset à intervalles réguliers (par exemple, toutes les 5 minutes). | Configurations simples avec un faible volume d'indexation |
| Piloté par les événements avec file d'attente différée (recommandé) | À chaque appel de IndexFileMeta, poussez le DatasetName dans une file d'attente différée. Récupérez périodiquement les noms de datasets et appelez CreateFigureClusteringTask au moins 10 secondes après le dernier appel IndexFileMeta pour ce dataset. |
Environnements de production avec indexation fréquente |
Prendre en compte la latence asynchrone
L'indexation des métadonnées est asynchrone. Concevez la logique de votre application en tenant compte de ces délais typiques :
| Opération | Latence typique |
|---|---|
| IndexFileMeta | ~10 secondes |
| CreateFigureClusteringTask | Jusqu'à 180 secondes (généralement quelques secondes) |
| SimpleQuery (après opérations asynchrones) | Attendez au moins 10 secondes après la fin de l'opération |
CreateFigureClusteringTask dépend de IndexFileMeta pour détecter les visages. Si vous vous abonnez aux résultats de IndexFileMeta via Simple Message Queue (anciennement MNS), attendez au moins 10 secondes après la fin de IndexFileMeta avant d'appeler CreateFigureClusteringTask. Cela garantit que les dernières informations sur les visages sont disponibles.
FAQ
Pourquoi le regroupement de visages ne génère-t-il aucun cluster ?
Comment trouver l'ID du cluster ?
Appelez QueryFigureClusters et examinez le champ ObjectId dans chaque entrée du tableau FigureClusters.
Comment interroger les images d'un cluster spécifique ?
Pourquoi les clusters générés ne sont-ils pas immédiatement consultables ?
Comment les images contenant plusieurs visages sont-elles gérées ?
Pourquoi SimpleQuery renvoie-t-il des visages d'autres clusters lors du filtrage par FigureClusterId ?
Comment obtenir les résultats d'une tâche CreateFacesSearchingTask sans configurer de notifications ?
Opérations connexes
| Opération | Description |
|---|---|
| CreateDataset | Créer un dataset |
| CreateBinding | Lier une source de données OSS à un dataset pour une indexation automatique |
| IndexFileMeta | Indexer les métadonnées de fichier dans un dataset |
| BatchIndexFileMeta | Indexer par lot les métadonnées de fichier |
| CreateFigureClusteringTask | Créer une tâche de regroupement de visages |
| QueryFigureClusters | Interroger tous les clusters de visages d'un dataset |
| SimpleQuery | Interroger des fichiers selon des conditions (par exemple, filtrer par ID de cluster) |
| GetFileMeta | Obtenir les métadonnées de fichier, y compris la qualité et l'angle du visage |
| GetTask | Obtenir le statut et les informations d'une tâche |
| ListTasks | Lister les tâches d'un projet |