Exemplo n.º 1
0
        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();
            }
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
        }