public User TestFromFeature(Guid frsId, MatrixString matrixString) { var db = new FrcContext(); var frs = db.FaceRecognitionSystems.Where(x => x.FaceRecognitionSystemId == frsId).FirstOrDefault(); if (frs == null) { throw new Exception("Face recognition system is not exist"); } User result; switch (frs.Type) { case "LDA": result = recognizeLDAbyFeature(frs.TypeSystemId, db, frsId, matrixString); break; default: throw new NotImplementedException(); } db.Dispose(); return(result); }
public MatrixString[] GetFrsParemeter(Guid frsId) { var db = new FrcContext(); var frs = db.FaceRecognitionSystems.Where(x => x.FaceRecognitionSystemId == frsId).FirstOrDefault(); if (frs == null) { throw new Exception("Face recognition system is not exist"); } MatrixString[] result; switch (frs.Type) { case "LDA": result = paramLDA(frs.TypeSystemId, db, frsId); break; default: throw new NotImplementedException(); } db.Dispose(); return(result); }
private User recognizeLDAbyFeature(Guid ldaId, FrcContext db, Guid frsId, MatrixString matrixString) { var systemEtalonCount = 1; // Копируется в testLDA нужно отрефакторить в более лучшем стиле. // var ldaEntity = db.LDAs.Where(x => x.LDAId == ldaId).FirstOrDefault(); // if (ldaEntity == null) // { // throw new Exception("LDA entity is not exist"); // } // var averageMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.AverageImageMatrixId).FirstOrDefault(); // var leftMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.LeftMatrixId).FirstOrDefault(); // var rightMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.RightMatrixId).FirstOrDefault(); // var averageMatrix = MatrixHelper.MatrixString2Matrix(averageMatrixString); // var leftMatrix = MatrixHelper.MatrixString2Matrix(leftMatrixString); // var rightMatrix = MatrixHelper.MatrixString2Matrix(rightMatrixString); // var ba = Convert.FromBase64String(imageByteArray); // var imageMatrix = DenseMatrix.OfArray(ImageHelper.ImageByteArray2pixelArray(ba)); // var featureMatrix = leftMatrix * (imageMatrix - averageMatrix) * rightMatrix; var featureMatrix = MatrixHelper.MatrixString2Matrix(matrixString); var etalonList = db.Etalons.Where(e => e.FaceRecognitionSystemId == frsId).ToList(); var etalonForUserTempList = etalonList.GroupBy(x => x.UserId).SelectMany(x => x.Take(systemEtalonCount)).ToList(); var userId = CompareToEtalonList(featureMatrix, etalonForUserTempList, db); return(db.Users.Where(x => x.UserId == userId).FirstOrDefault()); }
public User TestFromImage(Guid frsId, string imageByteArray, int systemEtalonCount) { var db = new FrcContext(); var frs = db.FaceRecognitionSystems.Where(x => x.FaceRecognitionSystemId == frsId).FirstOrDefault(); if (frs == null) { throw new Exception("Face recognition system is not exist"); } User result; switch (frs.Type) { case "LDA": result = recognizeLDA(frs.TypeSystemId, db, frsId, imageByteArray, systemEtalonCount); break; default: throw new NotImplementedException(); } db.Dispose(); return(result); }
private void testLDA(Guid ldaId, FrcContext db, Guid frsId) { // копируется в FacerecognitionRegistrator нужно вынести в отдельный файл. var ldaEntity = db.LDAs.Where(x => x.LDAId == ldaId).FirstOrDefault(); if (ldaEntity == null) { throw new Exception("LDA entity is not exist"); } var averageMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.AverageImageMatrixId).FirstOrDefault(); var leftMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.LeftMatrixId).FirstOrDefault(); var rightMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.RightMatrixId).FirstOrDefault(); var averageMatrix = MatrixHelper.MatrixString2Matrix(averageMatrixString); var leftMatrix = MatrixHelper.MatrixString2Matrix(leftMatrixString); var rightMatrix = MatrixHelper.MatrixString2Matrix(rightMatrixString); var testDatabaseUserList = db.DatabaseTestUsers.Where(x => x.FaceRecognitionSystemId == frsId).ToList(); // лучше добавить и использовать FK: List <Guid> test = testDatabaseUserList.Select(x => x.ImageId).ToList(); var imageList = db.Images.Where(x => test.Any(t => t == x.ImageId)).OrderBy(x => x.User.Username).ToList(); var etalonList = db.Etalons.Where(e => e.FaceRecognitionSystemId == frsId).ToList(); var maxEtalonsForUser = etalonList.GroupBy(x => x.UserId).Select(x => x.Count()).FirstOrDefault(); List <double> resultList = new List <double>(); for (int i = 0; i < maxEtalonsForUser; i++) { var etalonForUserTempList = etalonList.GroupBy(x => x.UserId).SelectMany(x => x.Take(i + 1)).ToList(); var performance = calcPerformance(imageList, leftMatrix, averageMatrix, rightMatrix, db, etalonForUserTempList); resultList.Add(performance); } }
private static void Main(string[] args) { using (FrcContext context = new FrcContext(new DbContextOptionsBuilder <FrcContext>().UseNpgsql( "Host = localhost; Port = 5442; Database = FrcTest; Username = postgres; Password = postgres").Options)) { FrcContextInitializer.Initialize(context); } }
public void startAddingDatabase() { var db = new FrcContext(); proccessDatabase(db); Console.ReadKey(); db.Dispose(); }
public List <FaceRecognitionSystem> GetFrsList() { var db = new FrcContext(); var frsList = db.FaceRecognitionSystems.ToList(); db.Dispose(); return(frsList); }
public List <DatabaseTestUser> GetList(Guid frsId) { var db = new FrcContext(); var frsList = db.DatabaseTestUsers.Where(x => x.FaceRecognitionSystemId == frsId).ToList(); db.Dispose(); return(frsList); }
public Image Get(Guid imageId) { var db = new FrcContext(); var imageEntity = db.Images.Where(x => x.ImageId == imageId).FirstOrDefault(); db.Dispose(); return(imageEntity); }
private MatrixString[] paramLDA(Guid ldaId, FrcContext db, Guid frsId) { var ldaEntity = db.LDAs.Where(x => x.LDAId == ldaId).FirstOrDefault(); if (ldaEntity == null) { throw new Exception("LDA entity is not exist"); } var averageMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.AverageImageMatrixId).FirstOrDefault(); var leftMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.LeftMatrixId).FirstOrDefault(); var rightMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.RightMatrixId).FirstOrDefault(); return(new MatrixString[] { averageMatrixString, leftMatrixString, rightMatrixString }); }
private void registerLDA(Guid ldaId, FrcContext db, List <Guid> imageIdList, Guid frsId) { var ldaEntity = db.LDAs.Where(x => x.LDAId == ldaId).FirstOrDefault(); if (ldaEntity == null) { throw new Exception("LDA entity is not exist"); } var averageMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.AverageImageMatrixId).FirstOrDefault(); var leftMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.LeftMatrixId).FirstOrDefault(); var rightMatrixString = db.MatrixStrings.Where(x => x.MatrixStringId == ldaEntity.RightMatrixId).FirstOrDefault(); var averageMatrix = MatrixHelper.MatrixString2Matrix(averageMatrixString); var leftMatrix = MatrixHelper.MatrixString2Matrix(leftMatrixString); var rightMatrix = MatrixHelper.MatrixString2Matrix(rightMatrixString); foreach (var imageId in imageIdList) { var imageEntity = db.Images.Where(x => x.ImageId == imageId).FirstOrDefault(); if (imageEntity == null) { continue; } var imageMatrix = DenseMatrix.OfArray(ImageHelper.ImageByteArray2pixelArray(imageEntity.ImageByteArray)); var featureMatrix = leftMatrix * (imageMatrix - averageMatrix) * rightMatrix; var featureMatrixString = MatrixHelper.convertToMatrixString(featureMatrix); db.MatrixStrings.Add(featureMatrixString); db.SaveChanges(); var etalon = new Entities.Etalon { EtalonId = Guid.NewGuid(), FaceRecognitionSystemId = frsId, FeatureMatrixId = featureMatrixString.MatrixStringId, ImageId = imageEntity.ImageId, RegistredDT = DateTime.UtcNow, UserId = imageEntity.UserId, }; db.Etalons.Add(etalon); db.SaveChanges(); } }
private void proccessDatabase(FrcContext db) { var orl = db.ImageDatabases.Where(x => x.DatabaseName == imageDatabaseName).FirstOrDefault(); if (orl != null) { Console.WriteLine("The database {0} already added;", imageDatabaseName); return; } analysisDatabase(inputDatabaseDir, imageDatabaseName); db.ImageDatabases.Add(imageDatabase); db.Users.AddRange(userList.AsEnumerable()); db.Images.AddRange(imageList.AsEnumerable()); db.SaveChanges(); Console.WriteLine("The database {0} successfully added;", imageDatabaseName); }
// to do: продумать как можно лучше работать с массивами пользователей, // чтобы не пришлось по сто раз извлекать для каждой регистрации в БД. public void RegisterUserList(List <Guid> imageIdList, Guid frsId) { var db = new FrcContext(); var frs = db.FaceRecognitionSystems.Where(x => x.FaceRecognitionSystemId == frsId).FirstOrDefault(); if (frs == null) { throw new Exception("Face recognition system is not exist"); } switch (frs.Type) { case "LDA": registerLDA(frs.TypeSystemId, db, imageIdList, frsId); break; default: throw new NotImplementedException(); } db.Dispose(); }
// Вообще лучше инкапсулировать всё что связано с LDA в отдельный модуль. public void TestFromDatabase(Guid frsId) { var db = new FrcContext(); var frs = db.FaceRecognitionSystems.Where(x => x.FaceRecognitionSystemId == frsId).FirstOrDefault(); if (frs == null) { throw new Exception("Face recognition system is not exist"); } switch (frs.Type) { case "LDA": testLDA(frs.TypeSystemId, db, frsId); break; default: throw new NotImplementedException(); } db.Dispose(); }
public Guid Create() { var db = new FrcContext(); var imdb = db.ImageDatabases.Where(x => x.DatabaseName == md.databaseName).FirstOrDefault(); if (imdb == null) { throw new Exception("Image database is not exist"); } totalTrainImageForUser = (int)Math.Floor( (double)imdb.TotalImageForUser * (Constants.HUNDRED_PERCENT - md.databaseTestImagesPercent) / Constants.HUNDRED_PERCENT); totalUserForTrain = (int)Math.Floor( (double)imdb.TotalUser * (Constants.HUNDRED_PERCENT - md.databaseTestUsersForOpenTaskPercent) / Constants.HUNDRED_PERCENT); if (totalTrainImageForUser == 0 || totalUserForTrain == 0) { throw new Exception("Not enaught images for user"); } // to do: обращаться ко всем элементам не очень так как для больших БД может не хватить памяти: var userListOfListsForTrain = db.Users.OrderBy(x => x.Username).Take(totalUserForTrain) .Select(x => x.Images.OrderBy(y => y.ImageName).Take(totalTrainImageForUser)).ToList(); foreach (var userImageList in userListOfListsForTrain) { List <Matrix <double> > userMatrixList = new List <Matrix <double> >(); foreach (var userImage in userImageList) { var imageMatrix = ImageHelper.ImageByteArray2pixelArray(userImage.ImageByteArray); userMatrixList.Add(DenseMatrix.OfArray(imageMatrix)); } trainImageLists.Add(userMatrixList); } Guid frsId; switch (md.trainName) { case "LDA": frsId = trainLDA(imdb, db); break; default: throw new NotImplementedException(); } // Записать все изображения пользователей, которые предназначены для тестирования БД на закрытом множестве. var userListOfListsForTest = db.Users.OrderBy(x => x.Username).Take(totalUserForTrain) .Select(x => x.Images.OrderBy(y => y.ImageName).Skip(totalTrainImageForUser)).ToList(); var testList = userListOfListsForTest.SelectMany(x => x.Select(i => new DatabaseTestUser { DatabaseTestUserId = Guid.NewGuid(), FaceRecognitionSystemId = frsId, ImageId = i.ImageId, })).ToList(); db.DatabaseTestUsers.AddRange(testList); db.SaveChanges(); db.Dispose(); // Зарегестрировать все изображения пользователей, которые учавствовали в обучении. var registrator = new FaceRecognitionRegistrator(); var imageIdList = userListOfListsForTrain.SelectMany(x => x.Select(y => y.ImageId)).ToList(); registrator.RegisterUserList(imageIdList, frsId); return(frsId); }
private Guid trainLDA(ImageDatabase imdb, FrcContext db) { if (!imdb.isSameImageSize || !imdb.isSameTotalImageForUser) { throw new NotImplementedException(); } // 1) Находим средний образ для всей базы исходных данных: var averageMatrix = Matrix <double> .Build.Dense(imdb.ImageHeight, imdb.ImageWidth); foreach (var userMatrixList in trainImageLists) { foreach (var userImage in userMatrixList) { averageMatrix = averageMatrix + userImage; } } var Xaverage = averageMatrix / (totalUserForTrain * totalTrainImageForUser); // 2) Находим средний образ для каждого класса: List <Matrix <double> > XclassAverageList = new List <Matrix <double> >(); foreach (var userMatrixList in trainImageLists) { var averageClassMatrix = Matrix <double> .Build.Dense(imdb.ImageHeight, imdb.ImageWidth); foreach (var userImage in userMatrixList) { averageClassMatrix = averageClassMatrix + userImage; } averageClassMatrix = averageClassMatrix / totalTrainImageForUser; XclassAverageList.Add(averageClassMatrix); } // 3) Вычислим матрицу внутриклассовой(w) ковариации относительно строк(R): var SwR = Matrix <double> .Build.Dense(imdb.ImageHeight, imdb.ImageHeight); for (int i = 0; i < trainImageLists.Count; i++) { foreach (var userImage in trainImageLists[i]) { SwR = SwR + (userImage - XclassAverageList[i]) * (userImage - XclassAverageList[i]).Transpose(); } } // 4) Вычислим матрицу межклассовой(b) ковариации относительно строк(R): var SbR = Matrix <double> .Build.Dense(imdb.ImageHeight, imdb.ImageHeight); foreach (var XclassAverage in XclassAverageList) { SbR = SbR + (XclassAverage - Xaverage) * (XclassAverage - Xaverage).Transpose(); } // 5) Вычислим матрицу внутриклассовой (w) ковариации относительно столбцов (C): var SwC = Matrix <double> .Build.Dense(imdb.ImageWidth, imdb.ImageWidth); for (int i = 0; i < trainImageLists.Count; i++) { foreach (var userImage in trainImageLists[i]) { SwC = SwC + (userImage - XclassAverageList[i]).Transpose() * (userImage - XclassAverageList[i]); } } // 6) Вычислим матрицу межклассовой (b) ковариации относительно столбцов (C): var SbC = Matrix <double> .Build.Dense(imdb.ImageWidth, imdb.ImageWidth); foreach (var XclassAverage in XclassAverageList) { SbC = SbC + (XclassAverage - Xaverage).Transpose() * (XclassAverage - Xaverage); } // 7) Сформируем общую матрицу рассеяния относительно строк: var StotalR = SwR.Inverse() * SbR; // Регуляризация (стр. 349): StotalR = StotalR + Constants.SMALL_VALUE * Matrix <double> .Build.Dense(imdb.ImageHeight, imdb.ImageHeight); // 8) Сформируем общую матрицу рассеяния относительно столбцов: var StotalC = SwC.Inverse() * SbC; // Регуляризация (стр. 349): StotalC = StotalC + Constants.SMALL_VALUE * Matrix <double> .Build.Dense(imdb.ImageWidth, imdb.ImageWidth); // 9) Решим задачу на собственные значения: var ReigResult = StotalR.Evd(); var CeigResult = StotalC.Evd(); // 10) Пропускаем сортировку по eigenvalues и ограничение по 95%. Берём только то, что написано в мнемоническом описании: // 11) Подготовка матриц для преобразования Карунена-Лоева: List <Vector <double> > rVectorList = new List <Vector <double> >(); for (int i = 0; i < md.trainMartixRightDimension; i++) { rVectorList.Add(ReigResult.EigenVectors.Column(i)); } // to do: значения матриц R как-то оказываются слева. Нужно переименовывать везде, а лучше ещё раз уточнить формулы: var eigMatrixLeft = Matrix <double> .Build.DenseOfColumnVectors(rVectorList.ToArray()).Transpose(); List <Vector <double> > cVectorList = new List <Vector <double> >(); for (int i = 0; i < md.trainMartixLeftDimension; i++) { cVectorList.Add(CeigResult.EigenVectors.Column(i)); } var eigMatrixRight = Matrix <double> .Build.DenseOfColumnVectors(cVectorList.ToArray()); var averageImageMatrixString = MatrixHelper.convertToMatrixString(Xaverage); var leftMatrixString = MatrixHelper.convertToMatrixString(eigMatrixLeft); var rightMatrixString = MatrixHelper.convertToMatrixString(eigMatrixRight); db.MatrixStrings.Add(averageImageMatrixString); db.MatrixStrings.Add(leftMatrixString); db.MatrixStrings.Add(rightMatrixString); db.SaveChanges(); var ldaEntity = new LDA { AverageImageMatrixId = averageImageMatrixString.MatrixStringId, LDAId = Guid.NewGuid(), LeftMatrixId = leftMatrixString.MatrixStringId, RightMatrixId = rightMatrixString.MatrixStringId, }; db.LDAs.Add(ldaEntity); db.SaveChanges(); var frs = new Entities.FaceRecognitionSystem { FaceRecognitionSystemId = Guid.NewGuid(), MnemonicDescription = md.originalDescription, Type = "LDA", TypeSystemId = ldaEntity.LDAId, InputImageHeight = imdb.ImageHeight, InputImageWidth = imdb.ImageWidth, CreatedDT = DateTime.UtcNow, }; db.FaceRecognitionSystems.Add(frs); db.SaveChanges(); return(frs.FaceRecognitionSystemId); }
private Guid CompareToEtalonList(DenseMatrix featureMatrix, List <Etalon> etalonForUserTempList, FrcContext db) { var test = etalonForUserTempList.Select(x => x.FeatureMatrixId).ToList(); var matrixStringList = db.MatrixStrings.Where(x => test.Any(y => y == x.MatrixStringId)).ToList(); List <double> comparisonDist = new List <double>(); foreach (var etalonMatrix in matrixStringList) { var etalon = MatrixHelper.MatrixString2Matrix(etalonMatrix); var compare = etalon - featureMatrix; var sqrDist = compare.AsColumnMajorArray().Sum(x => x * x); comparisonDist.Add(sqrDist); } var index = comparisonDist.IndexOf(comparisonDist.Min()); var answerMatrixId = matrixStringList[index].MatrixStringId; return(db.Etalons.Where(x => x.FeatureMatrixId == answerMatrixId).FirstOrDefault().UserId); }
private double calcPerformance(List <Image> imageList, DenseMatrix leftMatrix, DenseMatrix averageMatrix, DenseMatrix rightMatrix, FrcContext db, List <Etalon> etalonForUserTempList) { // тестируем изображения лиц: int correct = 0; foreach (var image in imageList) { var imageMatrix = DenseMatrix.OfArray(ImageHelper.ImageByteArray2pixelArray(image.ImageByteArray)); var featureMatrix = leftMatrix * (imageMatrix - averageMatrix) * rightMatrix; var userId = CompareToEtalonList(featureMatrix, etalonForUserTempList, db); if (userId == image.UserId) { correct += 1; } } double performance = (double)correct / imageList.Count * Constants.HUNDRED_PERCENT; return(performance); }