В программировании есть много разных способов аутентификации и каждая из них имеет как свои плюсы, так и минусы. В этой статье я хотел бы сделать обзор библиотеки, позволяющей с легкостью добавить аутентификацию лица в ваше .NET приложение.

Пару слов обо мне

Меня зовут Салахетдинов Орхан, и я — .NET-разработчик. Люблю изучать что-то новое в сфере программирования (и не только) и хочу внести свою лепту в развитие open-source. Еще хотел бы добавить, что это моя первая статья, я бы хотел написать еще одну (возможно, и несколько) статей про системы распознавания лиц и как они работают на простом языке. Если будет хороший актив и фидбек, то почему бы и нет? Судите, как хотите, так как я рад любому фидбеку, исключение — тотальная аннигиляция поста (опционально).

P.S Вторая статья уже готова - тут

С чего все началось?

Не так давно, буквально несколько месяцев назад, мне стала любопытна тема computer vision и ее часть — face recognition. Мне всегда нравилась функция FaceID от Apple, так как она очень удобная и практичная, и я подумал: есть ли такая библиотека для платформы .NET? К сожалению, после недолгого ресерчинга я так и не нашел чего-то похожего для .NET. В итоге я решил создать свою библиотеку аутентификации лица. Цель данной библиотеки — прежде всего пиар показать .NET- (и не только) разработчикам, как легко можно использовать Face Authentication в своих проектах. Она, к слову, есть как в NuGet так и в GitHub

Приступим

Для начала установим сам Nuget

dotnet add package FaceAuth

Хотел бы добавить, что при скачивании данного Nuget-пакета вам дополнительно скачаются его зависимости, а именно Emgu.CV и Emgu.CV.runtime.windows. Если у вас Linux или Mac, то следовательно заменяем Emgu.CV.runtime.windows на Emgu.CV.runtime.ваша ос.

После установки библиотеки мы можем написать простейший код для аутентификации лица.

using FaceAuth;

var auth = new FaceAuthProvider();

// Check and Initialize out camera
if (auth.CameraInitialize())
{
    // Initialize FaceRecognizer model
    auth.LoadFaceRecognizer();
    
    //Register
    auth.RegisterIFace("The name of the person you are registering", 10);

    // Recognize face
    auth.Recognize();
}
else
{
    Console.WriteLine("Your Camera Not Found!");
}

Разберем код детально

1.

var auth = new FaceAuthProvider();

Происходит инициализация DNN (глубокой нейронной сети) для нахождения и выделения лица и самой модели для определения лица. Также при первой сборке проекта в пути \bin\Debug\net6.0\ создается папка Assets, в которой будут два файла: deploy.prototxt и res10_300x300_ssd_iter_140000_fp16.caffemodel. Эти файлы нужны для инициализации нашей DNN.

2.

auth.CameraInitialize()

Как и понятно по названию, происходит инициализация нашей камеры, а точнее — ее поиск. Если есть камера, нам вернется true, иначе — false.

auth.LoadFaceRecognizer();

В данном коде происходит поиск и обучение модели распознавания лиц.

Во-первых, идет поиск папки TrainedFaces, в которой находятся лица для обучения. Если такой не имеется, то она создается. Если папка существует, то оттуда берутся все фотографии лиц, и они скармливаются модели.

Структура хранения лиц для обучения выглядит следующим образом:

└── TrainedFaces/           # Папка для хранения изображений лиц
    ├── Имя 1/              # Имя зарегестрированного человека
        ├── Фотография1.jpg
        ├── Фотография2.jpg
        ├── Фотография3.jpg
    ├── Имя 2/              # Имя зарегестрированного человека
        ├── Фотография1.jpg
        ├── Фотография2.jpg
        ├── Фотография3.jpg
    ├── Имя 3/              # Имя зарегестрированного человека
        ├── Фотография1.jpg
        ├── Фотография2.jpg
        ├── Фотография3.jpg                

Все изображения, конечно же, черно-белые для более эффективной работы модели распознавания лиц.

4.

auth.RegisterIFace("The name of the person you are registering", 10);

Тут происходит сам процесс регистрирования лиц. Под словом регистрирования подразумевается их сохранение в проекте, по структуре, которая описана выше.

5.

auth.Recognize();

Ну и наконец само распознавание лица. Первое что делает метод Recognize() так это проверяет обучена ли модель, если нет то он выдает исключение Recognition Model not trained.

Про саму модель распознавания лиц

Наша модель распознавания лиц, а именно Fisher Face Recognizer, использует алгоритмы Principal Component Analysis (PCA) и Linear Discriminant Analysis (LDA) для извлечения характеристических признаков лица. Не стоит вдаваться в подробности о том, как в принципе работают модели распознавания лиц в этой статье. Об этом стоит написать отдельную статью, но могу вкратце сказать, что наша модель смотрит на разные части лица и ищет те, которые помогают отличить одного человека от другого. Она сравнивает новое лицо с лицами, на которых она тренировалась, и определяет, зарегистрировано оно или же нет.

Советы

Вот советы из GitHub самой библиотеки.

  • Для большой работы нужно от 50-200 изображений одного человека в разных положениях головы.

  • Вы можете поместить auth.Recognize() в цикл из 10 итераций и получить хотя бы 1 true для успешной аутентификации.

        // Recognize face
        for (int i = 0; i < 10; i++)
        {
            if (auth.Recognize())
            {
                Console.WriteLine("Successful authentication");
                return;
            }
        }
    
        Console.WriteLine("Failed authentication");
  • Recognize() желательно делать не в бесконечном цикле, для более эффективной аутентификации.

  • Рекомендуется сделать анти-спам систему для защиты от взлома.

    bool TryRecognize(FaceAuthProvider _auth, ref int _recognizeCount)
    {
        _recognizeCount++;
        return _auth.Recognize();
    }
    
    int recognizeCount = 0;
    
    for (int i = 0; i < 10; i++)
    {
        if (recognizeCount <= 5)
        {
            TryRecognize(auth, ref recognizeCount);
        }
        else
        {
            Console.WriteLine("You cant recognize more");
            return;
        }
    }

Заключение

Я бы очень хотел увидеть FaceAuth в крупных проектах, возможно, я добавлю его и в свои проекты. Я надеюсь, я смог внести хоть какой-то вклад в open-source-сообщество, ну и для .NET-разработчиков в целом. Надеюсь, вам понравилась данная статья, жду комментариев и активности :)

Комментарии (3)


  1. Kolonist
    02.07.2023 23:05

    Хотелось бы именно подробностей о модели. Как устроена, на чем написана, как тренировалась, какая точность, какая пропускная способность, какие особенности распознавания и т.п.


    1. Kolonist
      02.07.2023 23:05
      +1

      Глянул исходники. Получается, что это не Ваша модель, а просто стандартная старенькая OpenCV-шная.

      А Вы не хотите попробовать заюзать ML.NET и какую-нибудь современную претрененную модель? Думаю, результат будет в разы точнее, вопрос лишь в необходимых ресурсах.


      1. Or1onn Автор
        02.07.2023 23:05

        Как вы правильно упомянули, тут используется модель FisherFaceRecognizer, которая была натренирована на AT&T Database of Faces. В данный момент ведется работа по интеграции новой обученной модели в библиотеку, но это займет определенное время. Так же в планах были переводить лицо в 3D модель для более точного и быстрого распознавания лица. Так как это только первая версия библиотеки, обновлений и изменений будет много.