【问题标题】:How to stop adding the same person again in FaceAPI persongroup如何停止在 FaceAPI 人员组中再次添加同一个人
【发布时间】:2019-07-01 10:53:45
【问题描述】:

有没有办法停止在 FaceAPI 人员组中添加同一个人? 问题是已经在 persongroup 中的用户添加了不同的名称。

下面是我写的方法。它返回要添加到人员组的人员 GUID。

public async Task<Guid> Register(IEnumerable<MediaFile> photos)
{
    var personGroupId = "XYXNXNX"

    var allPersonGroups = await _faceServiceClient.ListPersonGroupsAsync();

    if (allPersonGroups?.Any(x => x.PersonGroupId == personGroupId) == false)
    {
        await _faceServiceClient.CreatePersonGroupAsync(personGroupId, "HFFGFGFD"); // creating a new person group if not exits.
    }

    foreach (var photo in photos)
    {
        using (var stream = photo.GetStream())
        {
            var faces = await _faceServiceClient.DetectAsync(stream);

            if (faces?.Length == 0)
            {
                throw new CustomException(_translatorService.NoFaceFound);
            }

            if (faces?.Length > 1)
            {
                throw new CustomException(_translatorService.MultipleFacesFound);
            }
        }
    }

    var person = await _faceServiceClient.CreatePersonAsync(personGroupId, Guid.NewGuid().ToString());

    foreach (var photo in photos)
    {
        await _faceServiceClient.AddPersonFaceInPersonGroupAsync(personGroupId, person.PersonId, photo.GetStream());
    }

    await _faceServiceClient.TrainPersonGroupAsync(personGroupId);

    return person.PersonId;
}

【问题讨论】:

    标签: c# azure microsoft-cognitive face-recognition face-api


    【解决方案1】:

    你做了什么

    根据您的代码,您正在执行以下操作:

    1. 通过其PersonGroupId 获取PersonGroup,如果没有则创建 现有
    2. 然后对于方法参数中提供的每张照片:
      • 使用人脸 API 中的Detect 方法检测是否有人脸:如果找到 0 或大于 1,则抛出异常
    3. 新建一个Person,添加到之前的PersonGroup
    4. 然后对于方法参数中提供的每张照片:将人脸添加到创建的Person中
    5. 最后,训练PersonGroup

    避免为现有人员创建新的Person

    如果你想避免创建一个新的Person,如果你已经有同一个人的照片,你可以简单地用其中一张照片调用方法Identify(如果你知道的话,任何一张)正如您的代码所暗示的那样,所有这些都来自同一个人。

    此步骤应在以下行之前完成:

    var person = await _faceServiceClient.CreatePersonAsync(personGroupId, Guid.NewGuid().ToString());
    

    在这里你可以做这样的事情(我使用了最新的 Nuget Package for Face API 中的方法,可用here

    public async Task<Guid> Register(IEnumerable<MediaFile> photos)
    {
        var personGroupId = "XYXNXNX";
    
        var allPersonGroups = await _faceClient.PersonGroup.ListAsync();
    
        if (allPersonGroups?.Any(x => x.PersonGroupId == personGroupId) == false)
        {
            await _faceClient.PersonGroup.CreateAsync(personGroupId, "HFFGFGFD"); // creating a new person group if not exits.
        }
    
        var facesIdFromPhotos = new List<Guid>();
    
        foreach (var photo in photos)
        {
            using (var stream = photo.GetStream())
            {
                var faces = await _faceClient.Face.DetectWithStreamAsync(stream);
    
                if (faces?.Length == 0)
                {
                    throw new Exception("NoFaceFound");
                }
    
                if (faces?.Length > 1)
                {
                    throw new Exception("MultipleFacesFound");
                }
    
                facesIdFromPhotos.Add(((Microsoft.Azure.CognitiveServices.Vision.Face.Models.DetectedFace)faces[0]).FaceId);
            }
        }
    
        // Check similarity, with 1 face from the previous detected faces
        var similarityPerson = await _faceClient.Face.IdentifyAsync(facesIdFromPhotos.Take(1).ToList(), personGroupId);
    
        Guid targetPersonId;
        if (similarityPerson[0].Candidates?.Count > 0)
        {
            targetPersonId = similarityPerson[0].Candidates[0].PersonId;
        }
        else
        {
            var createdPerson = await _faceClient.PersonGroupPerson.CreateAsync(personGroupId, Guid.NewGuid().ToString());
            targetPersonId = createdPerson.PersonId;
        }
    
        // Add faces to Person (already existing or not)
        foreach (var photo in photos)
        {
            await _faceClient.PersonGroupPerson.AddFaceFromStreamAsync(personGroupId, targetPersonId, photo.GetStream());
        }
    
        await _faceClient.PersonGroup.TrainAsync(personGroupId);
    
        return targetPersonId;
    }
    

    最后一件事:为什么要抛出异常?不能直接跳过 0 张或多于 1 张脸的照片吗?

    【讨论】:

    • 使用这种方法,我无法添加与已注册人相似的人。在我尝试注册相似对象时,IdentifyAsync 正在返回已注册的人。
    • 当然可以,通过使用Identify 结果中的置信度得分。如果新人相似但不是同一个人,你只需要使用足够高的置信度分数,你就会低于该值
    猜你喜欢
    • 1970-01-01
    • 2023-04-06
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多