0

我正在使用 Azure Face APi 来检测视频流中的人脸,但是对于每个检测到的人脸 Azure 返回一个唯一的 faceId(这正是文档所说的)。

问题是,假设 Mr.ABC 出现在 20 个视频帧中,生成了 20 个唯一的 faceId。我想要 Azure Face 应该返回给我一个单独的 faceId 或一组专门为 Mr.ABC 生成的 FaceId 的东西,这样我就可以知道它是同一个人在镜头前停留了 x 时间。

我已阅读 Azure Facegrouping 和 Azure FindSimilar 的文档,但不明白如何在实时视频流的情况下使其工作。

下面给出了我用于使用 Azure 人脸检测人脸的代码:

from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials
from azure.cognitiveservices.vision.face.models import TrainingStatusType, Person, SnapshotObjectType, OperationStatusType
import cv2
import os
import requests
import sys,glob, uuid,re
from PIL import Image, ImageDraw
from urllib.parse import urlparse
from io import BytesIO
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient,__version__

face_key = 'XABC' #API key
face_endpoint = 'https://XENDPOINT.cognitiveservices.azure.com' #endpoint, e.g. 'https://westus.api.cognitive.microsoft.com'

credentials = CognitiveServicesCredentials(face_key)
face_client = FaceClient(face_endpoint, credentials)

camera = cv2.VideoCapture(0)
samplenum =1
im = ""
work_dir = os.getcwd()

person_group_id = 'test02-group'
target_person_group_id = str(uuid.uuid4())
face_ids = []

#cv2 font
font = cv2.FONT_HERSHEY_SIMPLEX
#empty tuple
width = ()
height = ()
left=0
bottom=0
def getRectangle(faceDictionary):
    rect = faceDictionary.face_rectangle
    left = rect.left
    top = rect.top
    right = left + rect.width
    bottom = top + rect.height
    
    return ((left, top), (right, bottom))

while True:
    check,campic = camera.read()
    samplenum=samplenum+1
    cv2.imwrite("live_pics/"+str(samplenum)+".jpg",campic)
    path = work_dir+"/live_pics/"+str(samplenum)+".jpg"
    #im = cv2.imread("pics/"+str(samplenum)+".jpg")
    stream = open(path, "r+b")
    detected_faces = face_client.face.detect_with_stream(
        stream,
        return_face_id=True,
        return_face_attributes=['age','gender','emotion'],recognitionModel="recognition_03")
    for face in detected_faces:
        width,height = getRectangle(face)
        cv2.rectangle(campic,width,height,(0,0,170),2)
        face_ids.append(face.face_id)
    #cv2.waitKey(100);
    if(samplenum>10):
        break
    cv2.imshow("campic", campic)
    if cv2.waitKey(1) == ord("q"):
        break

camera.release()
cv2.destroyAllWindows()   
4

2 回答 2

2

人脸 API 没有什么神奇之处:你必须为找到的每个人脸分 2 个步骤来处理它。

我建议使用“查找相似”:

  • 一开始,创建一个“FaceList”
  • 然后处理您的视频:
    • 每帧人脸检测
    • 对于找到的每个人脸,在创建的人脸列表上使用查找类似操作。如果没有匹配(有足够的信心),则将人脸添加到人脸列表中。

最后,您的面孔列表将包含在视频中找到的所有不同的人。


对于您的实时用例,不要对 PersonGroup / LargePersonGroup 使用“识别”操作(这两者之间的选择取决于组的大小),因为您将被组培训的需要所困。例如,您将执行以下操作:

  • 第 1 步、第 1 次:为此执行生成 PersonGroup/LargePersonGroup
  • 第 2 步,N 次(对于您要识别人脸的每个图像):
    • 步骤 2a:人脸检测
    • 步骤 2b:根据 PersonGroup / LargePersonGroup 在每个检测到的人脸上“识别”人脸
    • 步骤 2c:对于每个未识别的人脸,将其添加到 PersonGroup / LargePersonGroup。

这里的问题是,在 2c 之后,您必须再次训练您的团队。即使不是很长,也不能实时使用,因为它会太长。

于 2020-11-30T08:26:43.590 回答
2

根据我的理解,您希望显示一个人的姓名/身份,而不是从人脸 API 检测到的人脸 ID。

如果是这样,在您通过人脸检测 API 获取人脸 ID 后,您应该使用人脸识别 API来执行此操作。如果人脸可以被 Azure 人脸服务识别,你可以得到一个人 ID,有了这个 ID,你就可以使用PersonGroup Person API来获取这个人的信息。

我还为你写了一个简单的演示,在这个演示中,只有一张图像,我们可以将其图像为视频帧。我用一个超人创建了一个人组,并为他添加了一些面孔。

这是下面的代码:

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
import numpy as np
import asyncio
import io
import glob
import os
import sys
import time
import uuid
import requests
from urllib.parse import urlparse
from io import BytesIO
from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials

imPath = "<image path>";
ENDPOINT = '<endpoint>'
KEY = '<key>'
PERSON_GROUP_ID = '<person group name>'

face_client = FaceClient(ENDPOINT, CognitiveServicesCredentials(KEY))
im = np.array(Image.open(imPath), dtype=np.uint8)

faces = face_client.face.detect_with_stream(open(imPath, 'r+b'),recognition_model='recognition_03');

# Create figure and axes
fig,ax = plt.subplots()

 # Display the image
ax.imshow(im)

for i in range(len(faces)):
    face = faces[i]
    rect =patches.Rectangle((face.face_rectangle.left,face.face_rectangle.top),face.face_rectangle.height,face.face_rectangle.width,linewidth=1,edgecolor='r',facecolor='none')
    detected_person = face_client.face.identify([face.face_id],PERSON_GROUP_ID)[0]
    if(len(detected_person.candidates) > 0):
        person_id = detected_person.candidates[0].person_id
        person = face_client.person_group_person.get(PERSON_GROUP_ID,person_id)
        plt.text(face.face_rectangle.left,face.face_rectangle.top,person.name,color='r')
    else:
        plt.text(face.face_rectangle.left,face.face_rectangle.top,'unknown',color='r')

    
    ax.add_patch(rect)

plt.show()

结果:

在此处输入图像描述

于 2020-12-01T01:15:03.490 回答