takuya-takeuchi / FaceRecognitionDotNet

The world's simplest facial recognition api for .NET on Windows, MacOS and Linux
MIT License
1.27k stars 308 forks source link

System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception. #225

Closed maoshanli closed 1 year ago

maoshanli commented 1 year ago

The exception is an accidental exception,but it makes the program crash. The following is the exception: System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception. at DlibDotNet.NativeMethods.LossMetric_operator_matrixs(Int32 id, IntPtr obj, MatrixElementType element_type, IntPtr[] matrix_array, Int32 matrix_array_len, Int32 templateRows, Int32 templateColumns, UInt32 batch_size, IntPtr& ret) at DlibDotNet.Dnn.LossMetric.Operator[T](IEnumerable`1 images, UInt64 batchSize)

The initialization of ShapePredictor was written in the initialization of a class by singleton pattern. I have scanned the related issues like #5,I have checked the model file full path(D:\RoomCX\VideoToPicture) , I also download the .dat files serveral times,the problem still exist. Please let me know how i can correct this

Thanks

takuya-takeuchi commented 1 year ago

@takuya-takeuchi Could you show me minimal code to reproduce issue?

LossMetric_operator_matrixs is invoked when inference. Therefore, I guess you try to invoke this methods from multiple thread. If so, you must create multiple FaceRecognition object per thread.

Thanks.

maoshanli commented 1 year ago

The code: public static FaceRecognitionEx Inst { get { if (m_instance == null) m_instance = new FaceRecognitionEx(); return m_instance; } } private FaceRecognitionEx() { detector = Dlib.GetFrontalFaceDetector(); sp = ShapePredictor.Deserialize("shape_predictor_68_face_landmarks.dat"); net = DlibDotNet.Dnn.LossMetric.Deserialize("dlib_face_recognition_resnet_model_v1.dat"); } FrontalFaceDetector detector; ShapePredictor sp; LossMetric net; public List<float[]> GetFeature(string imgpath) { /*.......... var faces = new List<Matrix>(); try { using (var img = Dlib.LoadImageAsMatrix(imgpath)) { foreach (var face in detector.Operator(img)) { var shape = sp.Detect(img, face); var faceChipDetail = Dlib.GetFaceChipDetails(shape, 150, 0.25); var faceChip = Dlib.ExtractImageChip(img, faceChipDetail);

                        faces.Add(faceChip);
                    }
                    /*.......
            catch
            {
                LogManager.face.Info($"[获取人脸特征失败]");
                features = null;
            }
            foreach (var face in faces)
                face.Dispose();
        } while (false);
        return features;
  }

The function " GetFeature" was invoked by multiple thread.By my understanding,the “shape_predictor_68_face_landmarks.dat” loaded once can improve the performance.I have tried to load the .dat for each image,the cpu can't support.

takuya-takeuchi commented 1 year ago

The function " GetFeature" was invoked by multiple thread.

In GetFeature, net.Operator is invoked from multiple thread, doesn't it? If so, this schenario is not be supported. https://github.com/davisking/dlib/issues/544#issuecomment-295119225

You have to create FaceRecognitionEx instance for each thread. Or you can invoke net.Operator on one thread by using lock mechanism.

DlibDotNet.Dnn.LossMetric would not be slow operation different from face detection.

maoshanli commented 1 year ago

Thank you very much!net.Operator invoked from multiple thread lead to the problem.I have sovled the problem.