takuya-takeuchi / DlibDotNet

Dlib .NET wrapper written in C++ and C# for Windows, MacOS, Linux and iOS
MIT License
485 stars 134 forks source link

External component throws an error #314

Open muneerhussain321 opened 3 months ago

muneerhussain321 commented 3 months ago

Summary of your issue

Environment

using System; using System.Collections.Generic; using DlibDotNet; using DlibDotNet.Dnn; using System.Runtime.InteropServices; using System.Reflection;

class Program { static void Main(string[] args) { // var DLL = Assembly.LoadFile(@"C:\Users\munee.nuget\packages\dlibdotnet\19.21.0.20220724\lib\netstandard2.0\DlibDotNet.dll"); // Paths to images and models string individualImagePath = @"D:\ArtificialIntelligence\ImageProcessing\1\ImageProcessing\ImageProcessing\CompareImages\srk.jpg"; string groupImagePath = @"D:\ArtificialIntelligence\ImageProcessing\1\ImageProcessing\ImageProcessing\CompareImages\group.jpg"; string shapePredictorPath = @"D:\ArtificialIntelligence\ImageProcessing\NewFolder2\shape_predictor_68_face_landmarks.dat"; string faceRecognitionModelPath = @"D:\ArtificialIntelligence\ImageProcessing\NewFolder2\dlib_face_recognition_resnet_model_v1.dat";

    // Load images
    var individualImage = Dlib.LoadImage<RgbPixel>(individualImagePath);
    var groupImage = Dlib.LoadImage<RgbPixel>(groupImagePath);

    // Detect faces in individual image
    var individualFaces = DetectFaces(individualImage, shapePredictorPath);

    // Detect faces in group image
    var groupFaces = DetectFaces(groupImage, shapePredictorPath);

    // Perform face recognition
    bool isSamePerson = PerformFaceRecognition(individualImage, individualFaces, groupImage, groupFaces, faceRecognitionModelPath);

    // Print result
    Console.WriteLine($"Is the individual in the group photo? {isSamePerson}");
}

static IEnumerable<FullObjectDetection> DetectFaces(Array2D<RgbPixel> image, string shapePredictorPath)
{
    using (var detector = Dlib.GetFrontalFaceDetector())
    using (var sp = ShapePredictor.Deserialize(shapePredictorPath))
    {
        var faces = detector.Operator(image);
        foreach (var face in faces)
        {
            yield return sp.Detect(image, face);
        }
    }
}

static bool PerformFaceRecognition(Array2D<RgbPixel> individualImage, IEnumerable<FullObjectDetection> individualFaces,
                               Array2D<RgbPixel> groupImage, IEnumerable<FullObjectDetection> groupFaces, string faceRecognitionModelPath)
{
    using (var net = LossMetric.Deserialize(faceRecognitionModelPath))
    {
        foreach (var individualFace in individualFaces)
        {
            var individualDescriptor = ExtractFaceDescriptor(individualImage, individualFace, net);

            foreach (var groupFace in groupFaces)
            {
                var groupDescriptor = ExtractFaceDescriptor(groupImage, groupFace, net);

                // Check if descriptors are valid
                if (individualDescriptor != null && groupDescriptor != null)
                {
                    double distance = ComputeEuclideanDistance(individualDescriptor, groupDescriptor);
                    if (distance < 0.6) // Threshold for face similarity
                    {
                        return true;
                    }
                }
            }
        }

        return false;
    }
}

static Matrix<float> ExtractFaceDescriptor(Array2D<RgbPixel> image, FullObjectDetection face, LossMetric net)
{
    // Extract face chip as Array2D<RgbPixel>
    var faceChip = Dlib.ExtractImageChip<RgbPixel>(image, Dlib.GetFaceChipDetails(face));

    // Create a new Matrix<RgbPixel> from the faceChip
    var faceChipMatrix = new Matrix<RgbPixel>(faceChip);

    // Pass the faceChipMatrix to net.Operator
    //check faceChipMatrix has valid data   
    if (faceChipMatrix.Size == 0)
    {
        return null;
    }
    //check outputLabels is not null
    //if(net.Operator<RgbPixel>(faceChipMatrix) == null)
    //{
    //    return null;
    //}   
    try
    {
        net.Operator<RgbPixel>(faceChipMatrix);
    }
    catch (Exception e)
    {
        return null;
    }   
    var outputLabels = net.Operator<RgbPixel>(faceChipMatrix);

    // Extract the first descriptor if available
    if (outputLabels.Count > 0)
    {
        return outputLabels[0];
    }
    else
    {
        return null;
    }
}

static string MatrixToString<T>(Matrix<T> matrix) where T : struct
{
    if (matrix == null)
    {
        return "Matrix is null";
    }

    // Check if the matrix is empty
    if (matrix.Size == 0)
    {
        return "Matrix is empty";
    }

    // Construct a string representation of the matrix
    string matrixString = "";
    for (int i = 0; i < matrix.Rows; i++)
    {
        for (int j = 0; j < matrix.Columns; j++)
        {
            matrixString += matrix[i, j] + "\t";
        }
        matrixString += "\n";
    }

    return matrixString;
}
static double ComputeEuclideanDistance(Matrix<float> vec1, Matrix<float> vec2)
{
    double sum = 0;
    for (int i = 0; i < vec1.Size; i++)
    {
        sum += Math.Pow(vec1[i] - vec2[i], 2);
    }
    return Math.Sqrt(sum);
}

}

muneerhussain321 commented 3 months ago

i am in windows environment

muneerhussain321 commented 3 months ago

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](IEnumerable1 images, UInt64 batchSize) at DlibDotNet.Dnn.LossMetric.Operator[T](Matrix1 image, UInt64 batchSize) at Program.ExtractFaceDescriptor(Array2D`1 image, FullObjectDetection face, LossMetric net) in D:\ArtificialIntelligence\ImageProcessing\1\ImageProcessing\ImageProcessing\Program.cs:line 101