A clusterização facial agrupa imagens com rostos semelhantes em um conjunto de dados. Cada cluster representa uma pessoa, permitindo localizar todas as fotos de um indivíduo específico em um único cluster.
Casos de uso comuns:
Álbuns faciais em unidades na nuvem -- Organize fotos automaticamente por pessoa para gerar álbuns personalizados.
Monitoramento residencial -- A clusterização facial registra os rostos dos membros da família. Quando o rosto de um estranho aparece, a clusterização falha e envia um alerta. Isso ajuda a identificar e lidar com pessoas e eventos perigosos o mais rápido possível, garantindo a segurança da sua família.
Gestão de clientes no varejo -- Elimine duplicatas de imagens de clientes para obter contagens precisas de tráfego e analise o comportamento de compra para marketing direcionado.
Como funciona
A clusterização facial segue um fluxo de trabalho de API em três etapas:
1. Index images CreateBinding, IndexFileMeta, or BatchIndexFileMeta
|
v
2. Cluster faces CreateFigureClusteringTask
|
v
3. Query results QueryFigureClusters --> SimpleQuery (images per cluster)
Indexe imagens em um conjunto de dados. Use CreateBinding para vinculação automática ou IndexFileMeta / BatchIndexFileMeta para indexação manual. Crie o conjunto de dados com CreateDataset.
Execute a clusterização facial. Chame CreateFigureClusteringTask para agrupar rostos no conjunto de dados. Esta operação é incremental e processa apenas novas imagens desde a última execução.
Consulte clusters e imagens. Utilize QueryFigureClusters para listar todos os clusters e, em seguida, use SimpleQuery para recuperar todas as imagens de um cluster específico.
Pré-requisitos
Antes de começar, certifique-se de que:
As imagens estejam indexadas em um conjunto de dados via CreateBinding, IndexFileMeta ou BatchIndexFileMeta
O conjunto de dados contenha pelo menos 3 imagens da mesma pessoa
Pelo menos 3 dessas imagens atendam aos requisitos de rosto em alta definição listados abaixo
Requisitos para rosto em alta definição
|
Critério |
Limiar |
|
Área do rosto |
Maior que 75 x 75 pixels |
|
HeadPose |
Valor absoluto de cada elemento (Pitch, Roll, Yaw) menor que 30 |
|
FaceQuality |
Maior que 0,8 |
Chame GetFileMeta para verificar o ângulo do rosto e os valores de qualidade das imagens indexadas.
Após a criação de um cluster, rostos que não atendem a esses limiares ainda podem ser adicionados ao mesmo cluster. Para mais detalhes, consulte FAQ sobre gerenciamento de imagens.
Criar uma tarefa de clusterização facial
Chame CreateFigureClusteringTask para clusterizar rostos nas imagens indexadas em um conjunto de dados. Esta operação gera apenas clusters e não modifica as imagens originais.
As informações da tarefa são retidas por 7 dias após o início da execução. Após esse período, as informações deixam de estar disponíveis. Use um dos métodos a seguir para recuperar os resultados da tarefa:
Inscreva-se em uma fila do Simple Message Queue (anteriormente MNS) na mesma região do projeto IMM.
Crie uma instância do ApsaraMQ for RocketMQ 4.0 com um tópico e grupo na mesma região.
Utilize o EventBridge na mesma região para receber notificações de tarefas. Para detalhes sobre o formato da mensagem, consulte Exemplos de mensagens assíncronas.
Exemplo de solicitação
{
"ProjectName": "test-project",
"DatasetName": "test-dataset"
}
Exemplo de resposta
{
"TaskId": "CreateFigureClusteringTask-ba5784b8-f61e-485d-8ea0-****",
"RequestId": "42F4F8FD-006D-0EF0-8F2A-****",
"EventId": "140-1L5dh6eSUErqdxV1ZvJ****"
}
Uma resposta bem-sucedida inclui um TaskId confirmando a criação da tarefa de clusterização.
Código de exemplo (Python)
Consultar clusters faciais
Após a conclusão da clusterização, chame QueryFigureClusters para listar todos os clusters em um conjunto de dados. A resposta inclui os seguintes metadados para cada cluster:
|
Campo |
Descrição |
|
|
ID do cluster |
|
|
Número de rostos no cluster |
|
|
Número de imagens no cluster |
|
|
Gênero estimado |
|
|
Estatísticas de idade |
|
|
Imagem de capa com atributos faciais detalhados |
Exemplo de solicitação
{
"ProjectName": "test-project",
"DatasetName": "test-dataset"
}
Exemplo de resposta
{
"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-*****"
}
Neste exemplo, o conjunto de dados contém 2 clusters. O cluster Cluster-7bdbcedb-bd79-42e7-a1e2-b29a48532bd6 possui 16 imagens, enquanto o cluster Cluster-856be781-bf5a-46d7-8494-8d7c44f5e282 contém 5 imagens.
Código de exemplo (Python)
Consultar imagens em um cluster
Após obter as informações do cluster, chame SimpleQuery com o ID do cluster para listar todas as imagens nele contidas. O exemplo a seguir recupera imagens do cluster Cluster-7bdbcedb-bd79-42e7-a1e2-b29a48532bd6.
Exemplo de solicitação
{
"ProjectName": "test-project",
"DatasetName": "test-dataset",
"Query": "{\"Field\": \"Figures.FigureClusterId\", \"Operation\": \"eq\", \"Value\": \"Cluster-7bdbcedb-bd79-42e7-a1e2-b29a48532bd6\"}",
"MaxResults": 100
}
Exemplo de resposta
O cluster contém muitas imagens. O exemplo a seguir mostra os dados de uma única imagem.
{
"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-****"
}
Este resultado indica que o cluster inclui uma imagem em oss://bucket1/1.jpg.
Código de exemplo (Python)
Melhores práticas
Escolher uma frequência de clusterização
A operação CreateFigureClusteringTask é incremental, portanto não é necessário chamá-la após cada indexação de imagem. Duas abordagens recomendadas:
|
Abordagem |
Como funciona |
Quando usar |
|
Polling agendado |
Chame CreateFigureClusteringTask em cada conjunto de dados em intervalos regulares (por exemplo, a cada 5 minutos). |
Configurações simples com baixo volume de indexação |
|
Orientado a eventos com fila de atraso (recomendado) |
Sempre que IndexFileMeta for chamado, envie o |
Ambientes de produção com indexação frequente |
Considerar a latência assíncrona
A indexação de metadados é assíncrona. Projete a lógica da sua aplicação considerando estes atrasos típicos:
|
Operação |
Latência típica |
|
IndexFileMeta |
~10 segundos |
|
CreateFigureClusteringTask |
Até 180 segundos (geralmente alguns segundos) |
|
SimpleQuery (após operações assíncronas) |
Aguarde pelo menos 10 segundos após a conclusão |
A operação CreateFigureClusteringTask depende da IndexFileMeta para detectar rostos. Se você estiver inscrito nos resultados da IndexFileMeta via Simple Message Queue (anteriormente MNS), aguarde pelo menos 10 segundos após a conclusão da IndexFileMeta antes de chamar CreateFigureClusteringTask. Isso garante que as informações faciais mais recentes estejam disponíveis.
Perguntas frequentes
Por que a clusterização facial não gera nenhum cluster?
Como encontro o ID do cluster?
Chame QueryFigureClusters e verifique o campo ObjectId dentro de cada entrada no array FigureClusters.
Como consulto imagens em um cluster específico?
Por que os clusters gerados não são pesquisáveis imediatamente?
Como são tratadas imagens com múltiplos rostos?
Por que SimpleQuery retorna rostos de outros clusters ao filtrar por FigureClusterId?
Como obtenho resultados de CreateFacesSearchingTask sem configurar notificações?
Operações relacionadas
|
Operação |
Descrição |
|
Criar um conjunto de dados |
|
|
Vincular uma source de dados OSS a um conjunto de dados para indexação automática |
|
|
Indexar metadados de arquivo em um conjunto de dados |
|
|
Indexar metadados de arquivo em lote |
|
|
Criar uma tarefa de clusterização facial |
|
|
Consultar todos os clusters faciais em um conjunto de dados |
|
|
Consultar arquivos por condições (ex.: filtrar por ID de cluster) |
|
|
Obter metadados de arquivo, incluindo qualidade e ângulo do rosto |
|
|
Obter status e informações da tarefa |
|
|
Listar tarefas em um projeto |