/// <summary> /// Verifies that the specified faces belong to the same person. /// </summary> /// <returns>A <see cref="VerifyResult"/> indicating equivalence, with a confidence factor.</returns> /// <param name="face1">The first <see cref="Face"/>.</param> /// <param name="face2">The second <see cref="Face"/>.</param> public async Task <VerifyResult> Verify(Model.Face face1, Model.Face face2) { try { return(await Verify(face1.Id, face2.Id)); } catch (Exception ex) { Log.Error(ex); throw; } }
/// <summary> /// Verifies that the given face belongs to the specified <see cref="Person"/>. /// </summary> /// <returns>A <see cref="VerifyResult"/> indicating equivalence, with a confidence factor.</returns> /// <param name="face">The <see cref="Face"/> to verify.</param> /// <param name="person">The <see cref="Person"/> to verify the <c>face</c> against.</param> /// <param name="personGroup">The <see cref="PersonGroup"/> the given person belongs to.</param> public async Task <VerifyResult> Verify(Model.Face face, Person person, PersonGroup personGroup) { try { return(await Verify(face.Id, person.Id, personGroup.Id)); } catch (Exception ex) { Log.Error(ex); throw; } }
/// <summary> /// Adds (saves/persists) a detected <see cref="Face"/> for the given <see cref="Person"/>. /// </summary> /// <param name="person">The <see cref="Person"/> to add a face for.</param> /// <param name="personGroup">The <see cref="PersonGroup"/> the person is a part of.</param> /// <param name="face">The detected <see cref="Face"/> to add. This will typically come from the Detect method.</param> /// <param name="photoStreamProvider">A <see cref="Func{Stream}"/> that provides a stream to the image data containing the Face.</param> /// <param name="userData">A custom user data string to store with the person's Face.</param> /// <remarks>Note that photoStreamProvider should return a stream that can be disposed - this will be used in a using() statement on a background thread. /// The image stream provided should be the same original image that was used to detect the Face - the <see cref="FaceRectangle"/> must be valid and should contain the correct face.</remarks> /// <seealso cref="DetectFacesInPhoto(Func{Stream})"/> public async Task AddFaceForPerson(Person person, PersonGroup personGroup, Model.Face face, Func <Stream> photoStreamProvider, string userData = null) { try { using (var stream = await Task.Run(photoStreamProvider)) { await AddFaceForPerson(person, personGroup, face, stream, userData); } } catch (Exception ex) { Log.Error(ex); throw; } }
/// <summary> /// Deletes a persisted <see cref="Face"/> for the given <see cref="Person"/>. /// </summary> /// <param name="person">The <see cref="Person"/> the given <see cref="Face"/> belongs to.</param> /// <param name="personGroup">The <see cref="PersonGroup"/> the person is a part of.</param> /// <param name="face">The persisted <see cref="Face"/> to delete.</param> public async Task DeletePersonFace(Person person, PersonGroup personGroup, Model.Face face) { try { await DeletePersonFace(person.Id, personGroup.Id, face.Id); if (person.Faces.Contains(face)) { person.Faces.Remove(face); } } catch (Exception ex) { Log.Error(ex); throw; } }
/// <summary> /// Adds (saves/persists) a detected <see cref="Face"/> for the given <see cref="Person"/>. /// </summary> /// <param name="personId">The Id of the <see cref="Person"/> to add a face for.</param> /// <param name="personGroupId">The Id of the <see cref="PersonGroup"/> the person is a part of.</param> /// <param name="face">The detected <see cref="Face"/> to add. This will typically come from the Detect method.</param> /// <param name="stream">A stream to the image data containing the Face.</param> /// <param name="userData">A custom user data string to store with the person's Face.</param> /// <remarks>The Stream passed in to this method will NOT be disposed and should be handled by the calling client code. /// The image stream provided should be the same original image that was used to detect the Face - the <see cref="FaceRectangle"/> must be valid and should contain the correct face.</remarks> /// <seealso cref="DetectFacesInPhoto(Stream, bool, FaceAttributeType [])"/> public Task <string> AddFaceForPerson(string personId, string personGroupId, Model.Face face, Stream stream, string userData = null) { var tcs = new TaskCompletionSource <string> (); using (var data = NSData.FromStream(stream)) { Client.AddPersonFaceWithPersonGroupId( personGroupId, personId, data, userData, face.FaceRectangle.ToMPOFaceRect(), (result, error) => AdaptResultCallback(error, tcs, result, r => r.PersistedFaceId)) .Resume(); return(tcs.Task); } }
/// <summary> /// Adds (saves/persists) a detected <see cref="Face"/> for the given <see cref="Person"/>. /// </summary> /// <param name="person">The <see cref="Person"/> to add a face for.</param> /// <param name="personGroup">The <see cref="PersonGroup"/> the person is a part of.</param> /// <param name="face">The detected <see cref="Face"/> to add. This will typically come from the Detect method.</param> /// <param name="stream">A stream to the image data containing the Face.</param> /// <param name="userData">A custom user data string to store with the person's Face.</param> /// <remarks>The Stream passed in to this method will NOT be disposed and should be handled by the calling client code. /// The image stream provided should be the same original image that was used to detect the Face - the <see cref="FaceRectangle"/> must be valid and should contain the correct face.</remarks> /// <seealso cref="DetectFacesInPhoto(Stream, bool, FaceAttributeType [])"/> public async Task AddFaceForPerson(Person person, PersonGroup personGroup, Model.Face face, Stream stream, string userData = null) { try { var id = await AddFaceForPerson(person.Id, personGroup.Id, face, stream, userData); if (string.IsNullOrEmpty(id)) { throw new Exception("AddFaceForPerson Result returned null or empty face Id"); } face.Id = id; person.Faces.Add(face); } catch (Exception ex) { Log.Error(ex); throw; } }
/// <summary> /// Finds faces similar to <c>targetFace</c> in the given <c>faceList</c>. /// </summary> /// <returns>A list of <see cref="SimilarFaceResult"/> indicating similar face(s) and associated confidence factor.</returns> /// <param name="targetFace">The target <see cref="Face"/> to find similar faces to.</param> /// <param name="faceList">The face list containing faces to compare to <c>targetFace</c>.</param> /// <param name="maxCandidatesReturned">The maximum number of candidate faces to return.</param> /// <param name="matchMode">The <see cref="FindSimilarMatchMode"/> to use when comparing - matchFace or matchPerson (default).</param> /// <remarks><c>maxCandidatesReturned</c> and <c>matchMode</c> are not currently respsected on iOS due to native SDK limiations.</remarks> public async Task <List <SimilarFaceResult> > FindSimilar(Model.Face targetFace, List <Model.Face> faceList, int maxCandidatesReturned = 1, FindSimilarMatchMode matchMode = FindSimilarMatchMode.MatchPerson) { try { var faceIdList = faceList.Select(f => f.Id).ToArray(); var results = await FindSimilar(targetFace.Id, faceIdList, maxCandidatesReturned, matchMode); foreach (var similarFaceResult in results) { similarFaceResult.Face = faceList.FirstOrDefault(f => f.Id == similarFaceResult.FaceId); } return(results); } catch (Exception ex) { Log.Error(ex); throw; } }
/// <summary> /// Adds (saves/persists) a detected <see cref="Face"/> for the given <see cref="Person"/>. /// </summary> /// <param name="personId">The Id of the <see cref="Person"/> to add a face for.</param> /// <param name="personGroupId">The Id of the <see cref="PersonGroup"/> the person is a part of.</param> /// <param name="face">The detected <see cref="Face"/> to add. This will typically come from the Detect method.</param> /// <param name="stream">A stream to the image data containing the Face.</param> /// <param name="userData">A custom user data string to store with the person's Face.</param> /// <remarks>The Stream passed in to this method will NOT be disposed and should be handled by the calling client code. /// The image stream provided should be the same original image that was used to detect the Face - the <see cref="FaceRectangle"/> must be valid and should contain the correct face.</remarks> /// <seealso cref="DetectFacesInPhoto(Stream, bool, FaceAttributeType [])"/> public Task <string> AddFaceForPerson(string personId, string personGroupId, Model.Face face, Stream stream, string userData = null) { return(AdaptResultAction(() => Client.AddPersonFace(personGroupId, personId.ToUUID(), stream, userData, face.FaceRectangle.ToNativeFaceRect()), r => r?.PersistedFaceId?.ToString())); }
/// <summary> /// Attempts to Identify the given <see cref="Face"/> detectedFace against a trained <see cref="PersonGroup"/> containing 1 or more faces. /// </summary> /// <returns>A list of <see cref="IdentificationResult"/> containing <see cref="CandidateResult"/> indicating potential identification matches and the confidence factor for the match.</returns> /// <param name="personGroup">The <see cref="PersonGroup"/> to identify a <see cref="Face"/> against.</param> /// <param name="detectedFace">A detected face to use for the identification.</param> /// <param name="maxNumberOfCandidates">The max number of candidate matches to return.</param> public Task <List <IdentificationResult> > Identify(PersonGroup personGroup, Model.Face detectedFace, int maxNumberOfCandidates = 1) { return(Identify(personGroup, new Model.Face [] { detectedFace }, maxNumberOfCandidates)); }
/// <summary> /// Finds faces similar to <c>targetFace</c> in the given <c>faceList</c>. /// </summary> /// <returns>A list of <see cref="SimilarFaceResult"/> indicating similar face(s) and associated confidence factor.</returns> /// <param name="targetFace">The target <see cref="Face"/> to find similar faces to.</param> /// <param name="faceList">The face list containing faces to compare to <c>targetFace</c>.</param> /// <param name="maxCandidatesReturned">The maximum number of candidate faces to return.</param> /// <remarks><c>maxCandidatesReturned</c> is not currently respsected on iOS due to native SDK limiations.</remarks> public Task <List <SimilarFaceResult> > FindSimilar(Model.Face targetFace, List <Model.Face> faceList, int maxCandidatesReturned) { return(FindSimilar(targetFace, faceList, maxCandidatesReturned, FindSimilarMatchMode.MatchPerson)); }
/// <summary> /// Finds faces similar to <c>targetFace</c> in the given <c>faceList</c>. /// </summary> /// <returns>A list of <see cref="SimilarFaceResult"/> indicating similar face(s) and associated confidence factor.</returns> /// <param name="targetFace">The target <see cref="Face"/> to find similar faces to.</param> /// <param name="faceList">The face list containing faces to compare to <c>targetFace</c>.</param> public Task <List <SimilarFaceResult> > FindSimilar(Model.Face targetFace, List <Model.Face> faceList) { return(FindSimilar(targetFace, faceList, 1, FindSimilarMatchMode.MatchPerson)); }