FaceRecognitionDotNet: FaceRecognition.FaceEncodings() Too slow

I create a wpf demo for face compare, the code is as following:

        private void StartVideo()
        {
            tVideo = new Thread(new ThreadStart(() =>
            {
                using (var cap = new VideoCapture(0))
                {
                    if (!cap.IsOpened())
                        return;

                    OpenCvSharp.Point pLeftTop = new OpenCvSharp.Point();
                    OpenCvSharp.Point pRightBottom = new OpenCvSharp.Point();
                    int roiWidth = 260;
                    int roiHeight = 360;

                    Mat target = Cv2.ImRead("yuzifu.jpg");
                    var arrtarget = new byte[target.Width * target.Height * target.ElemSize()];
                    Marshal.Copy(target.Data, arrtarget, 0, arrtarget.Length);
                    var temptarget = Dlib.LoadImageData<RgbPixel>(arrtarget, (uint)target.Height, (uint)target.Width, (uint)(target.Width * target.ElemSize()));
                    var imgtarget = FaceRecognition.LoadImageData(temptarget);
                    var endodings = this._FaceRecognition.FaceEncodings(imgtarget).ToArray();

                    cap.FrameWidth = 800;
                    cap.FrameHeight = 600;
                    cap.FourCC = "MJPG";
                    using (Mat srcImg = new Mat())
                    {
                        while (running)
                        {
                            cap.Read(srcImg);
                            if (srcImg.Width > 0 && srcImg.Height > 0)
                            {
                                Cv2.Flip(srcImg, srcImg, FlipMode.Y);

                                pLeftTop.X = (srcImg.Width - roiWidth) / 2;
                                pLeftTop.Y = (srcImg.Height - roiHeight) / 2;
                                pRightBottom.X = pLeftTop.X + roiWidth;
                                pRightBottom.Y = pLeftTop.Y + roiHeight;
                                OpenCvSharp.Rect roi = new OpenCvSharp.Rect(pLeftTop.X, pLeftTop.Y, roiWidth, roiHeight);
                                Mat imageROI = srcImg.Clone(roi);

                                bool result = CompareFace(imageROI, endodings);

                                srcImg.Rectangle(pLeftTop, pRightBottom, Scalar.FromRgb(0, 255, 150));
                                Dispatcher.Invoke(()=>
                                {
                                    if (!srcImg.IsDisposed)
                                        FrontVideo.Source = srcImg.ToBitmapSource();
                                    Name.Text = result ? "Yuzifu" : "Unknow";
                                });
                            }
                        }
                    }
                }
            }));
            tVideo.Start();
        }

        private bool CompareFace(Mat source, FaceEncoding[] endtarget)
        {
            bool rtn = false;
            var arrsource = new byte[source.Width * source.Height * source.ElemSize()];
            Marshal.Copy(source.Data, arrsource, 0, arrsource.Length);
            var tempsource = Dlib.LoadImageData<RgbPixel>(arrsource, (uint)source.Height, (uint)source.Width, (uint)(source.Width * source.ElemSize()));

            using (var imgsource = FaceRecognition.LoadImageData(tempsource))
            {
                var locals = this._FaceRecognition.FaceLocations(imgsource);

                // too slow
                var endodings1 = this._FaceRecognition.FaceEncodings(imgsource, locals).ToArray();

                foreach (var encoding in endodings1)
                    foreach (var compareFace in FaceRecognition.CompareFaces(endtarget, encoding))
                    {
                        if (compareFace)
                        {
                            rtn = true;
                            break;
                        }
                    }

                foreach (var encoding in endodings1)
                    encoding.Dispose();
            }

            return rtn;
        }

        // Add func to FaceRecognition
        public static Image LoadImageData(Array2D<RgbPixel> array)
        {
            return new Image(new Matrix<RgbPixel>(array));
        }

By tracking the running time, execute FaceEncodings() need a lot of time, at least 600 milliseconds, many times more than 1 second.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 36 (20 by maintainers)

Most upvoted comments

I found that the Native.loss_metric_operator_matrixs() used a lot of time.