using Microsoft.Extensions.Configuration; using Microsoft.VisualStudio.TestTools.UnitTesting; using Phares.Shared; using Serilog; using System.Diagnostics; using System.Drawing.Imaging; using System.Reflection; using View_by_Distance.FaceRecognitionDotNet; using View_by_Distance.Metadata.Models; using View_by_Distance.Resize.Models; using View_by_Distance.Shared.Models; using View_by_Distance.Shared.Models.Stateless; using View_by_Distance.Shared.Models.Stateless.Methods; using View_by_Distance.TestsWithFaceRecognitionDotNet.Models; namespace View_by_Distance.TestsWithFaceRecognitionDotNet; [TestClass] public class UnitTestFace { private readonly ILogger _Logger; private readonly AppSettings _AppSettings; private readonly string _WorkingDirectory; private readonly Configuration _Configuration; private readonly IsEnvironment _IsEnvironment; private readonly IConfigurationRoot _ConfigurationRoot; private readonly Property.Models.Configuration _PropertyConfiguration; public UnitTestFace() { ILogger logger; AppSettings appSettings; string workingDirectory; Configuration configuration; IsEnvironment isEnvironment; IConfigurationRoot configurationRoot; LoggerConfiguration loggerConfiguration = new(); Property.Models.Configuration propertyConfiguration; Assembly assembly = Assembly.GetExecutingAssembly(); bool debuggerWasAttachedAtLineZero = Debugger.IsAttached || assembly.Location.Contains(@"\bin\Debug"); isEnvironment = new(processesCount: null, nullASPNetCoreEnvironmentIsDevelopment: debuggerWasAttachedAtLineZero, nullASPNetCoreEnvironmentIsProduction: !debuggerWasAttachedAtLineZero); IConfigurationBuilder configurationBuilder = new ConfigurationBuilder() .AddEnvironmentVariables() .AddJsonFile(isEnvironment.AppSettingsFileName); configurationRoot = configurationBuilder.Build(); appSettings = Models.Stateless.AppSettings.Get(configurationRoot); workingDirectory = IWorkingDirectory.GetWorkingDirectory(assembly.GetName().Name, appSettings.WorkingDirectoryName); Environment.SetEnvironmentVariable(nameof(workingDirectory), workingDirectory); _ = ConfigurationLoggerConfigurationExtensions.Configuration(loggerConfiguration.ReadFrom, configurationRoot); Log.Logger = loggerConfiguration.CreateLogger(); logger = Log.ForContext(); propertyConfiguration = Property.Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory); configuration = Models.Stateless.Configuration.Get(isEnvironment, configurationRoot, workingDirectory, propertyConfiguration); logger.Information("Complete"); _Logger = logger; _AppSettings = appSettings; _Configuration = configuration; _IsEnvironment = isEnvironment; _WorkingDirectory = workingDirectory; _ConfigurationRoot = configurationRoot; _PropertyConfiguration = propertyConfiguration; } [TestMethod] public void TestMethodNull() { Assert.IsFalse(_Logger is null); Assert.IsFalse(_AppSettings is null); Assert.IsFalse(_Configuration is null); Assert.IsFalse(_IsEnvironment is null); Assert.IsFalse(_WorkingDirectory is null); Assert.IsFalse(_ConfigurationRoot is null); Assert.IsFalse(_PropertyConfiguration is null); } private Property.Models.PropertyLogic GetPropertyLogic() { Property.Models.PropertyLogic result; if (_AppSettings.MaxDegreeOfParallelism is null) throw new ArgumentNullException(nameof(_AppSettings.MaxDegreeOfParallelism)); if (_Configuration?.PropertyConfiguration is null) throw new ArgumentNullException(nameof(_Configuration.PropertyConfiguration)); result = new(_AppSettings.MaxDegreeOfParallelism.Value, _Configuration.PropertyConfiguration); return result; } private static (Model model, PredictorModel predictorModel, ModelParameter modelParameter) GetModel(Configuration configuration) { (Model, PredictorModel, ModelParameter) result; Array array; Model? model = null; PredictorModel? predictorModel = null; array = Enum.GetValues(typeof(Model)); foreach (Model check in array) { if (configuration.ModelName.Contains(check.ToString())) { model = check; break; } } if (model is null) throw new Exception("Destination directory must have Model name!"); model = model.Value; array = Enum.GetValues(typeof(PredictorModel)); foreach (PredictorModel check in array) { if (configuration.PredictorModelName.Contains(check.ToString())) { predictorModel = check; break; } } if (predictorModel is null) throw new Exception("Destination directory must have Predictor Model name!"); predictorModel = predictorModel.Value; ModelParameter modelParameter = new() { CnnFaceDetectorModel = File.ReadAllBytes(Path.Combine(configuration.ModelDirectory, "mmod_human_face_detector.dat")), FaceRecognitionModel = File.ReadAllBytes(Path.Combine(configuration.ModelDirectory, "dlib_face_recognition_resnet_model_v1.dat")), PosePredictor5FaceLandmarksModel = File.ReadAllBytes(Path.Combine(configuration.ModelDirectory, "shape_predictor_5_face_landmarks.dat")), PosePredictor68FaceLandmarksModel = File.ReadAllBytes(Path.Combine(configuration.ModelDirectory, "shape_predictor_68_face_landmarks.dat")) }; result = new(model.Value, predictorModel.Value, modelParameter); return result; } [TestMethod] public void TestGetPixelPercentage() { double pixelPercentage; pixelPercentage = Location.GetPixelPercentage(1, 1, 10, 10, 100, 100); Assert.IsTrue(pixelPercentage == 0.0505d); pixelPercentage = Location.GetPixelPercentage(50, 50, 60, 60, 100, 100); Assert.IsTrue(pixelPercentage == 0.5555d); } [TestMethod] public void TestMethodFace() { string sourceFileName = "IMG_0067.jpg"; string sourceDirectoryName = "Mackenzie Prom 2017"; // string sourceFileName = "Fall 2005 (113).jpg"; // string sourceDirectoryName = "=2005.3 Fall"; // string sourceFileName = "DSCN0534.jpg"; // string sourceDirectoryName = "Logan Swimming Lessons 2013"; // string sourceFileName = "DSC_4913.jpg"; // string sourceDirectoryName = "Disneyland 2014"; // string sourceFileName = "Logan Michael Sept 08 (193).jpg"; // string sourceDirectoryName = "=2008.2 Summer Logan Michael"; if (_Configuration.ForceMetadataLastWriteTimeToCreationTime is null) throw new ArgumentNullException(nameof(_Configuration.ForceMetadataLastWriteTimeToCreationTime)); if (_Configuration.ForceResizeLastWriteTimeToCreationTime is null) throw new ArgumentNullException(nameof(_Configuration.ForceResizeLastWriteTimeToCreationTime)); if (_Configuration.OutputQuality is null) throw new ArgumentNullException(nameof(_Configuration.OutputQuality)); if (_Configuration.OverrideForResizeImages is null) throw new ArgumentNullException(nameof(_Configuration.OverrideForResizeImages)); if (_Configuration.PropertiesChangedForMetadata is null) throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForMetadata)); if (_Configuration.PropertiesChangedForResize is null) throw new ArgumentNullException(nameof(_Configuration.PropertiesChangedForResize)); if (_Configuration.NumberOfJitters is null) throw new ArgumentNullException(nameof(_Configuration.NumberOfJitters)); if (_Configuration.NumberOfTimesToUpsample is null) throw new ArgumentNullException(nameof(_Configuration.NumberOfTimesToUpsample)); int g = 1; int r = 1; string original = "Original"; List parseExceptions = new(); Property.Models.A_Property? property = null; Property.Models.PropertyHolder propertyHolder; Dictionary imageResizeKeyValuePairs; List> subFileTuples = new(); List> metadataCollection; int length = _PropertyConfiguration.RootDirectory.Length; string outputResolution = _Configuration.OutputResolutions[0]; Property.Models.PropertyLogic propertyLogic = GetPropertyLogic(); (Model model, PredictorModel predictorModel, ModelParameter modelParameter) = GetModel(_Configuration); string sourceDirectory = Path.Combine(_PropertyConfiguration.RootDirectory, sourceDirectoryName); _Logger.Information(_Configuration.ModelDirectory); string aPropertySingletonDirectory = Property.Models.Stateless.IResult.GetResultsDateGroupDirectory(_PropertyConfiguration, nameof(Property.Models.A_Property), "{}"); B_Metadata metadata = new(_Configuration.ForceMetadataLastWriteTimeToCreationTime.Value, _Configuration.PropertiesChangedForMetadata.Value); (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters) = C_Resize.GetTuple(_Configuration.OutputExtension, _Configuration.OutputQuality.Value); C_Resize resize = new(_Configuration.ForceResizeLastWriteTimeToCreationTime.Value, _Configuration.OverrideForResizeImages.Value, _Configuration.PropertiesChangedForResize.Value, _Configuration.ValidResolutions, imageCodecInfo, encoderParameters); propertyLogic.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_PropertyConfiguration, model, predictorModel, sourceDirectory, nameof(Property.Models.A_Property), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Properties for each image", collectionDescription: string.Empty)); metadata.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_PropertyConfiguration, model, predictorModel, sourceDirectory, nameof(B_Metadata), outputResolution, includeResizeGroup: false, includeModel: false, includePredictorModel: false, contentDescription: string.Empty, singletonDescription: "Metadata as key value pairs", collectionDescription: string.Empty)); resize.AngleBracketCollection.AddRange(Property.Models.Stateless.IResult.GetDirectoryInfoCollection(_PropertyConfiguration, model, predictorModel, sourceDirectory, nameof(C_Resize), outputResolution, includeResizeGroup: true, includeModel: false, includePredictorModel: false, contentDescription: "Resized image", singletonDescription: "Resize dimensions for each resolution", collectionDescription: string.Empty)); string sourceDirectoryFile = ".json"; Property.Models.FileHolder fileHolder = new(Path.Combine(sourceDirectory, sourceFileName)); string relativePath = Property.Models.Stateless.IPath.GetRelativePath(fileHolder.FullName, length); sourceDirectory = Path.Combine(aPropertySingletonDirectory, sourceDirectoryName); propertyHolder = new(g, sourceDirectory, sourceDirectoryFile, relativePath, r, fileHolder, property, false, false, null, null); Assert.IsNotNull(propertyHolder.ImageFileHolder); property = propertyLogic.GetProperty(propertyLogic.AngleBracketCollection[0], propertyHolder, subFileTuples, parseExceptions); (int _, metadataCollection) = metadata.GetMetadataCollection(subFileTuples, parseExceptions, propertyHolder); imageResizeKeyValuePairs = resize.GetResizeKeyValuePairs(subFileTuples, parseExceptions, original, metadataCollection, property, propertyHolder); Property.Models.FileHolder resizedFileHolder = new(Path.Combine(resize.AngleBracketCollection[0].Replace("<>", "()"), Path.GetFileName(propertyHolder.ImageFileHolder.FullName))); propertyHolder.SetResizedFileHolder(resizedFileHolder); resize.SaveResizedSubfile(outputResolution, subFileTuples, propertyHolder, original, property, imageResizeKeyValuePairs); propertyHolder.SetResizedFileHolder(Property.Models.FileHolder.Refresh(resizedFileHolder)); Assert.IsNotNull(propertyHolder.ResizedFileHolder); Image? image = FaceRecognition.LoadImageFile(propertyHolder.ResizedFileHolder.FullName); Assert.IsNotNull(image); FaceRecognition faceRecognition = FaceRecognition.Create(modelParameter); List locations = faceRecognition.FaceLocations(model, image, _Configuration.NumberOfTimesToUpsample.Value, sortByPixelPercentage: true); Assert.IsTrue(locations.Count == 2); List<(FacePart, FacePoint[])[]> faceLandmarks = faceRecognition.GetFaceLandmarkCollection(image, _Configuration.NumberOfTimesToUpsample.Value, locations, predictorModel, model); Assert.IsTrue(faceLandmarks.Count == 2); faceLandmarks = faceRecognition.GetFaceLandmarkCollection(image, _Configuration.NumberOfTimesToUpsample.Value, faceLocations: null, predictorModel, model); Assert.IsTrue(faceLandmarks.Count == 2); List faceEncodings = faceRecognition.FaceEncodings(image, _Configuration.NumberOfTimesToUpsample.Value, knownFaceLocation: null, _Configuration.NumberOfJitters.Value, predictorModel, model); Assert.IsTrue(faceEncodings.Count == 2); List faceDistances = FaceRecognition.FaceDistances(faceEncodings, faceEncodings[0]); Assert.IsTrue(faceDistances.Count == 2); Assert.IsNotNull(sourceFileName); } }