-
Notifications
You must be signed in to change notification settings - Fork 137
Description
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);
}
}