/// <summary>
        /// Compare a face encoding to a known face encoding and get a euclidean distance for comparison face.
        /// </summary>
        /// <param name="faceEncoding">The face encoding to compare.</param>
        /// <param name="faceToCompare">The face encoding to compare against.</param>
        /// <returns>The euclidean distance for comparison face. If 0, faces are completely equal.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="faceEncoding"/> or <paramref name="faceToCompare"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="faceEncoding"/> or <paramref name="faceToCompare"/> is disposed.</exception>
        public static double FaceDistance(FaceEncoding faceEncoding, FaceEncoding faceToCompare)
        {
            if (faceEncoding == null)
            {
                throw new ArgumentNullException(nameof(faceEncoding));
            }
            if (faceToCompare == null)
            {
                throw new ArgumentNullException(nameof(faceToCompare));
            }
            if (faceEncoding.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(faceEncoding));
            }
            if (faceToCompare.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(faceToCompare));
            }

            if (faceEncoding.Encoding.Size == 0)
            {
                return(0);
            }

            using (var diff = faceEncoding.Encoding - faceToCompare.Encoding)
                return(DlibDotNet.Dlib.Length(diff));
        }
        /// <summary>
        /// Compare a known face encoding against a candidate encoding to see if they match.
        /// </summary>
        /// <param name="knownFaceEncoding">A known face encodings.</param>
        /// <param name="faceEncodingToCheck">A single face encoding to compare against a known face encoding.</param>
        /// <param name="tolerance">The distance between faces to consider it a match. Lower is more strict. The default value is 0.6.</param>
        /// <returns>A True/False value indicating which known a face encoding matches the face encoding to check.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="knownFaceEncoding"/> or <paramref name="faceEncodingToCheck"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="knownFaceEncoding"/> or <paramref name="faceEncodingToCheck"/>.</exception>
        public static bool CompareFace(FaceEncoding knownFaceEncoding, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d)
        {
            if (knownFaceEncoding == null)
            {
                throw new ArgumentNullException(nameof(knownFaceEncoding));
            }
            if (faceEncodingToCheck == null)
            {
                throw new ArgumentNullException(nameof(faceEncodingToCheck));
            }
            if (knownFaceEncoding.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(knownFaceEncoding));
            }
            if (faceEncodingToCheck.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(faceEncodingToCheck));
            }

            return(FaceDistance(knownFaceEncoding, faceEncodingToCheck) <= tolerance);
        }
        /// <summary>
        /// Returns an enumerable collection of face feature data corresponds to all faces in specified image.
        /// </summary>
        /// <param name="image">The image contains faces. The image can contain multiple faces.</param>
        /// <param name="knownFaceLocation">The enumerable collection of location rectangle for faces. If specified null, method will find face locations.</param>
        /// <param name="numJitters">The number of times to re-sample the face when calculating encoding.</param>
        /// <returns>An enumerable collection of face feature data corresponds to all faces in specified image.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="image"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="image"/> or this object is disposed.</exception>
        public IEnumerable <FaceEncoding> FaceEncodings(Image image, IEnumerable <Location> knownFaceLocation = null, int numJitters = 1)
        {
            if (image == null)
            {
                throw new ArgumentNullException(nameof(image));
            }
            if (image.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(image));
            }
            if (this.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(FaceEncoding));
            }

            var rawLandmarks = this.RawFaceLandmarks(image, knownFaceLocation, PredictorModel.Small);

            foreach (var landmark in rawLandmarks)
            {
                var ret = new FaceEncoding(FaceRecognitionModelV1.ComputeFaceDescriptor(this._FaceEncoder, image, landmark, numJitters));
                landmark.Dispose();
                yield return(ret);
            }
        }
        /// <summary>
        /// Compare an enumerable collection of face encoding to a known face encoding and get an enumerable collection of euclidean distance for comparison face.
        /// </summary>
        /// <param name="faceEncodings">The enumerable collection of face encoding to compare.</param>
        /// <param name="faceToCompare">The face encoding to compare against.</param>
        /// <returns>The enumerable collection of euclidean distance for comparison face. If 0, faces are completely equal.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="faceEncodings"/> or <paramref name="faceToCompare"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="faceToCompare"/> is disposed. Or <paramref name="faceEncodings"/> contains disposed object.</exception>
        public static IEnumerable <double> FaceDistances(IEnumerable <FaceEncoding> faceEncodings, FaceEncoding faceToCompare)
        {
            if (faceEncodings == null)
            {
                throw new ArgumentNullException(nameof(faceEncodings));
            }
            if (faceToCompare == null)
            {
                throw new ArgumentNullException(nameof(faceToCompare));
            }
            if (faceToCompare.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(faceToCompare));
            }

            var array = faceEncodings.ToArray();

            if (array.Any(encoding => encoding.IsDisposed))
            {
                throw new ObjectDisposedException($"{nameof(faceEncodings)} contains disposed object.");
            }

            if (array.Length == 0)
            {
                yield break;
            }

            foreach (var faceEncoding in array)
            {
                using (var diff = faceEncoding.Encoding - faceToCompare.Encoding)
                    yield return(DlibDotNet.Dlib.Length(diff));
            }
        }
        /// <summary>
        /// Compare an enumerable collection of face encodings against a candidate encoding to see if they match.
        /// </summary>
        /// <param name="knownFaceEncodings">An enumerable collection of known face encodings.</param>
        /// <param name="faceEncodingToCheck">A single face encoding to compare against the enumerable collection.</param>
        /// <param name="tolerance">The distance between faces to consider it a match. Lower is more strict. The default value is 0.6.</param>
        /// <returns>An enumerable collection of True/False values indicating which known face encodings match the face encoding to check.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="knownFaceEncodings"/> or <paramref name="faceEncodingToCheck"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="faceEncodingToCheck"/> is disposed. Or <paramref name="knownFaceEncodings"/> contains disposed object.</exception>
        public static IEnumerable <bool> CompareFaces(IEnumerable <FaceEncoding> knownFaceEncodings, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d)
        {
            if (knownFaceEncodings == null)
            {
                throw new ArgumentNullException(nameof(knownFaceEncodings));
            }
            if (faceEncodingToCheck == null)
            {
                throw new ArgumentNullException(nameof(faceEncodingToCheck));
            }
            if (faceEncodingToCheck.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(faceEncodingToCheck));
            }

            var array = knownFaceEncodings.ToArray();

            if (array.Any(encoding => encoding.IsDisposed))
            {
                throw new ObjectDisposedException($"{nameof(knownFaceEncodings)} contains disposed object.");
            }

            if (array.Length == 0)
            {
                yield break;
            }

            foreach (var faceEncoding in array)
            {
                yield return(FaceDistance(faceEncoding, faceEncodingToCheck) <= tolerance);
            }
        }
Example #6
0
        //public IEnumerable<Location[]> BatchFaceLocations(IEnumerable<Image> faceImages, int numberOfTimesToUpsample = 1, int batchSize = 128)
        //{
        //    var faceImagesArray = faceImages.ToArray();
        //    var rawDetectionsBatched = this.RawFaceLocationsBatched(faceImagesArray, numberOfTimesToUpsample, batchSize).ToArray();

        //    for (var index = 0; index < rawDetectionsBatched.Length; index++)
        //    {
        //        var faces = rawDetectionsBatched[index];
        //        var image = faceImagesArray[index];
        //        yield return faces.Select(rect => TrimBound(rect.Rect, image.Width, image.Height)).ToArray();
        //    }
        //}

        /// <summary>
        /// Compare a list of face encodings against a candidate encoding to see if they match.
        /// </summary>
        /// <param name="knownFaceEncodings">A list of known face encodings.</param>
        /// <param name="faceEncodingToCheck">A single face encoding to compare against the list.</param>
        /// <param name="tolerance">The distance between faces to consider it a match. Lower is more strict. The default value is 0.6.</param>
        /// <returns>A list of True/False values indicating which known face encodings match the face encoding to check.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="knownFaceEncodings"/> or <paramref name="faceEncodingToCheck"/> is null.</exception>
        /// <exception cref="ObjectDisposedException"><paramref name="faceEncodingToCheck"/> is disposed. Or <paramref name="knownFaceEncodings"/> contains disposed object.</exception>
        public static IEnumerable <bool> CompareFaces(IEnumerable <FaceEncoding> knownFaceEncodings, FaceEncoding faceEncodingToCheck, double tolerance = 0.6d)
        {
            if (knownFaceEncodings == null)
            {
                throw new ArgumentNullException(nameof(knownFaceEncodings));
            }
            if (faceEncodingToCheck == null)
            {
                throw new ArgumentNullException(nameof(faceEncodingToCheck));
            }
            if (faceEncodingToCheck.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(faceEncodingToCheck));
            }

            var array = knownFaceEncodings.ToArray();

            if (array.Any(encoding => encoding.IsDisposed))
            {
                throw new ObjectDisposedException($"{nameof(knownFaceEncodings)} contains disposed object.");
            }

            return(array.Select(matrix => FaceDistance(matrix, faceEncodingToCheck) <= tolerance));
        }
 public FaceEncodingData(FaceEncoding faceEncoding, double distance)
 {
     this.faceEncoding = faceEncoding;
     this.distance     = distance;
 }