Перейти к содержимому
Compvision.ru
al072

Обновление модели для распознавания лиц

Recommended Posts

Всем доброго времени суток! Уважаемые господа форумчане, нужен ваш совет каким путем пойти чтобы не потратить даром времени и не наломать дров.

Адаптирую программу для распознавания лиц из книги Mastering OpenCV глава 8 под свои нужды. Хочу чтобы появилась возможность сохранять модель распознавания лиц, и в любой момент после перезапуска программы в нее можно было добавить новые лица, метки или удалить старые.

На данный момент нашел способ который сохраняет модель в файл и загружает ее из файла, но в моем случае это не подходит, так как если после перезапуска программы я вновь начну обучать модель, а затем сохранять ее в ранее созданный файл, все старые данные удаляться и запишеться только текущая тренированная модель:

Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
model->train(array of images,array of lables);
model->save("C:\\eigendataset.yml");
model->load("C:\\eigendataset.yml");

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

Или может существует более правильный способ для онлайн тренировки модели с последующем сохранением, изменением и загрузкой? Заранее благодарю за советы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Главные компоненты, вычисляются для задания базиса, его Вы и записываете в файл.

При добавлении лиц, вы проецируете лицо в этот базис и получаете его координаты (несколько десятков чисел).

Запоминаете известные лица (которые у Вас имеют имена).

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

Находите ближайшее, если расстояние меньше порогового это и есть опознанное лицо, если нет, то лицо отсутствует в базе.

 

ЗЫ: Если нужно что то серьезное для распознавания лиц, то посмотрите OpenFace: http://cmusatyalab.github.io/openface/

 

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
36 минуты назад, Smorodov said:

Большое спасибо за комментарии.

>>Главные компоненты, вычисляются для задания базиса, его Вы и записываете в файл.

Мой вопрос заключается в том, каким образом можно изменять ранее записанный базис? Добавлять в него координаты новых лиц, либо удалять координаты старых. Например я добавил фото 5 человек в vector<Mat>, в vector<Int> добавил lables от 1-5 для этих человек, далее я создаю базис по средствам model->train(vector<Mat>, в vector<Int>); и сохраняю этот базис model->save(); для последующей работы и выхожу из программы. Повторно запускаю программу и теберь я не заново создаю базис, а загружаю из существующего файла model->load(); но теперь мне необходимо добавить еще допустим координаты 3-х новых лиц в этот базис и скажем удалить координаты 1 старого лица которое в нем уже есть. Подскажите пожалуйста как мне лучше реализовать этот функционал? И вообще может я двигаюсь не в том направлении?

>>ЗЫ: Если нужно что то серьезное для распознавания лиц, то посмотрите OpenFace: http://cmusatyalab.github.io/openface/

Обязательно посмотрю.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Базис - система координат, среднее лицо ее нуль, собственные лица - ее оси.

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

 

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
3 минуты назад, Smorodov said:

Базис - система координат, среднее лицо ее нуль, собственные лица - ее оси.

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

 

То есть получается, что тот файл который я сохраняю как 

model->save(eigenfaces.yml)

Это не набор координат лиц и меток этих лиц, которые я присваивал в методе model->train()? Или я чтото не так понимаю..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

https://github.com/MasteringOpenCV/code/tree/master/Chapter8_FaceRecognition

По всей видимости тут используются классически PCA и LDA и они не предусматривают пересчета базиса.

По сути вы можете добавлять и удалять новые ID пользователей и искать их в "старом базисе", возможно старый базис будет достаточно хорош это надо проверить.

Есть методы которые позволяют делать апдейт базиса типа incremental / online pca, но насколько это будет лучше надо тестировать, т.к. базис выученный этими методами по идее "сходится" к базису выученному на полной выборке.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Модель здесь, это система координат.

Вы можете проецировать в нее лица (project), это позволяет из W*H мерного вектора (полной картинки), получить N мерный (по количеству собственных векторов) вектор  с минимальной потерей информации.

Насколько существенна потеря, можно оценить при помощи unproject, который производит реконструкцию обратно в изображение лица.

Дальнейшие действия аналогичны действиям с точками на бумаге, только каждая точка N мерная.

Есть известные точки из базы, и есть новые точки, которые вы хотите отнести к одной из известных точек.

Измеряете расстояния до каждой базовой точки, и выбираете ближайшую.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
34 минуты назад, mrgloom said:

https://github.com/MasteringOpenCV/code/tree/master/Chapter8_FaceRecognition

По всей видимости тут используются классически PCA и LDA и они не предусматривают пересчета базиса.

По сути вы можете добавлять и удалять новые ID пользователей и искать их в "старом базисе", возможно старый базис будет достаточно хорош это надо проверить.

Есть методы которые позволяют делать апдейт базиса типа incremental / online pca, но насколько это будет лучше надо тестировать, т.к. базис выученный этими методами по идее "сходится" к базису выученному на полной выборке.

Вы можете подсказать с помощью какой функции можно добавлять и удалять ид в базисе? Можно гдето посмотреть пример использования этих методов? Они есть в библиотеке opencv 2.4.11?

24 минуты назад, Smorodov said:

Модель здесь, это система координат.

Вы можете проецировать в нее лица (project), это позволяет из W*H мерного вектора (полной картинки), получить N мерный (по количеству собственных векторов) вектор  с минимальной потерей информации.

Насколько существенна потеря, можно оценить при помощи unproject, который производит реконструкцию обратно в изображение лица.

Дальнейшие действия аналогичны действиям с точками на бумаге, только каждая точка N мерная.

Есть известные точки из базы, и есть новые точки, которые вы хотите отнести к одной из известных точек.

Измеряете расстояния до каждой базовой точки, и выбираете ближайшую.

Как измерить расстояние до ближайших точек? Есть какаято функция в EigenFaceRecognizer()?

50 минут назад, al072 said:

 

 

1 час назад, Smorodov said:

 

ЗЫ: Если нужно что то серьезное для распознавания лиц, то посмотрите OpenFace: http://cmusatyalab.github.io/openface/

 

Как я понял это библиотека для python. Мой проект на С++ MFC. Если есть чтото более серьезное для примера под С++ чем из книги Mastering OpenCV глава 8, буду благодарен если поделитесь..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
14 часа назад, Smorodov said:

http://openbiometrics.org/ например.

Документация на эту библиотеку не изобилует примерами. Ктонибудь может подсказать где найти примеры использования этой библиотеки с каким либо GUI интерфейсом (MFC,Windows Forms). Я прочитал что библиотека основана на QT и OpenCV, но неувидел похожих функций, как например выделять лицо в квадрат при обнаружении?

Уважаемые форумчане, помоги с примером реализации распознавания лиц с помощью OpenCV.

Я не прошу готовый код, может ктонибудь описать сам механизм как лучше сделать самообучаемую систему распознавания лица, мне нужна помощь именно в конкретной задаче на которой я застрял: Каким образом можно добавлять новые лица в систему и пересохранять model->save() с вновь добавленными лицами? Или может быть сохранять модель в файл yml совсем не требуется? Подскажите плиз как реализовать этот механизм..

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

У многих возникают похожие проблемы с пониманием PCA.

Попробую по пунктам:

Собственный базис.

------------------------------

Рассматриваем входные изображения лиц как многомерные векторы.

Размерность векторов большая и равна произведению ширины изображения на его на высоту (и на количество каналов для цветного изображения).

Но так как яркости точек изображения не являются независимыми переменными, иначе был бы квадрат с шумом, значит меняются они по некоторому статистическому закону, так, чтобы всегда получалось лицо человека. Иными словами в пространстве, где любая точка - корректное лицо человека, для каждой точки разное, но всегда изображение лица.

Это пространство лиц имеет десятки осей, и каждая представляет некий важный признак выборки лиц (расстояние между глаз, высота лба, форма носа (конечно эти признаки будут не обязательно такие же как выделяют люди при взгляде на фото) ). 

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

Собственный векторы задают направления собственных осей в пространстве изображения, и, как правило, имеют очертания лиц.

Центром координат пространства лиц является среднее лицо.

 

Именно это пространство Вы и получаете после провдения PCA анализа, и, в общем случае, он не связан с распознаваемыми в будущем лицами. Для получения собственного базиса желательно использовать как можно большую выборку лиц.

Нам не нужно пересчитывать базис каждый раз при добавлении новых лиц.

 

Каждое лицо в такой системе будет иметь вид:

Любое лицо = среднее лицо + X1*первый собственный вектор + X2*второй собственный вектор+..

X1,X2 - координаты лица в базисе лиц.

 

Распознавание.

------------------------------

Теперь, когда у нас есть собственный базис, мы можем любое лицо представить в виде координат этого базиса (спроецировать вектор в новый базис).

В результате получим точку в пространстве лиц. 

 

Когда мы добавляем новую точку, мы просто где-нибудь в базе данных или в массиве, сохраняем координаты этой точки (координаты лица в базисе лиц). Не нужно пересчитывать базис !!! Если надо записываете эти точки в файл.

 

Когда мы хотим опознать лицо, проецируем новое лицо в базис лиц (Не нужно пересчитывать базис !!!), в результате получаем его координаты в базисе лиц.

 

Далее вычисляем расстояния от нашей точки (опознаваемого лица) до каждого из известных лиц, храняцихся в базе.

Расстояния обычно вычисляются с использованием Евклидовой метрики (корень из суммы квадратов разностей), или метрикой Махаланобиса (она учитывает дисперсии по осям и дает более точные результаты) ее реализация есть в OpenCV.

 

Находим ближайшее лицо из базы данных.

Сравниваем полученное расстояние с некторым порогом (устанавливается по результатам экспериментов), и, если порог не превышен. то выдаем это лицо как опознанное как ближайшее лицо из базы данных, если порог превышен, лицо не опознано.

 

Надеюсь стало понятнее.

 

 

 

 

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
24 minutes ago, Smorodov said:

Нам не нужно пересчитывать базис каждый раз при добавлении новых лиц

Понятно, что PCA для распознавания лиц в чистом виде не подходит. Но, сделаем предположение, что именно этот метод принят на некотором предприятии. Что делаем сначала?

1. Фоткаем всех сотрудников предприятия.

2. Берём готовый базис либо вычисляем его по отфотканым сотрудникам. Всё нормально, все корректно распознаются и не путаются, пропускной пункт работает нормально.

3. Предприятие чисто русское, сотрудники - славяне. Начальство берёт на работу 10 китайских эмигрантов, пусть работают. Внезапно оказывается, что в имеющемся базисе китайцы сильно отличаются от славян (круто!), но очень похожи друг на друга и система не может их различить. Что делать?

 

Сдаётся мне, что в реальности необходимость переучивания базиса возникнет. Как это делать? Да просто неудачные распознавания также добавлять в исходную выборку и заново полноценно переучивать. Нет?

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, правильно, базис должен быть сформирован по репрезентативной выборке, то есть вклюючать все возможные значимые вариации объекта.

Если добавляется подвид объектов, с некими сильными общими признаками (китайцы) отсутствующими в базисной выборке, то система, возможно, отнесет их к одному кластеру и опознает как одного человека, так как их общая проекция в существующем базисе будет близка к одной точке.

 

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Smorodov, спасибо за развернутый и подробный ответ! Перечитал вашу статью раз 5, но очень туго до меня доходит такая сложная информация. Есть как минимум прогресс с пониманием базиса. Теперь я знаю что каждый раз его пересчитывать не нужно. Раз так туго до меня доходит теория, давайте попробуем разобрать код, если вы не против. 

Ptr<FaceRecognizer>  model = Algorithm::create<FaceRecognizer>("FaceRecognizer.Eigenfaces");//Модель распознавания лица
vector<Mat> preprocessedFaces;// Массив для хранения полученных с камеры уже нормализованных лиц
vector<int> faceLabels;// Массив для хранения меток для каждого нового лица

// Запускаем режим сбора лиц с камеры MODE_COLLECT_FACES 
preprocessedFaces.push_back(cv::Mat уже обработанное лицо);// Предположим что мы собрали 100 снимков одного лица
faceLabels.push_back(1);//Петр Петрович Петров
preprocessedFaces.push_back(cv::Mat уже обработанное лицо);// Предположим что мы собрали 100 снимков другого лица
faceLabels.push_back(2);//Иван Иванович Иванов

// Далее мы тренируем PCA базис для этих двух человек
model->train(preprocessedFaces, faceLabels);
// Далее мы сохраняем наш натренированый базис в файл с расширением yml, чтобы после перезапуска программы больше не проходить процесс тренировки
model->save("C:\\eigen.yml");
// Далее мы переходим в режим распознавания лица MODE_RECOGNITION
reconstructedFace = reconstructFace(model, preprocessedFace);//Так как значение этой функции я не понимаю, приведу ниже ее реализацию и большая просьба может ктонибудь объяснить по строчно что означает каждая строчка этой функции

Mat reconstructFace(const Ptr<FaceRecognizer> model, const Mat preprocessedFace)
{
    try {

        
        Mat eigenvectors = model->get<Mat>("eigenvectors");// Что здесь происходит и для чего это???
        Mat averageFaceRow = model->get<Mat>("mean");// Что здесь происходит и для чего это???

        int faceHeight = preprocessedFace.rows;

        // Project the input image onto the PCA subspace. 
        Mat projection = subspaceProject(eigenvectors, averageFaceRow, preprocessedFace.reshape(1,1));// Что здесь происходит и для чего это???
        

        // Generate the reconstructed face back from the PCA subspace. 
        Mat reconstructionRow = subspaceReconstruct(eigenvectors, averageFaceRow, projection);  // Что здесь происходит и для чего это???    

        // Convert the float row matrix to a regular 8-bit image. Note that we
        // shouldn't use "getImageFrom1DFloatMat()" because we don't want to normalize
        // the data since it is already at the perfect scale.

        // Make it a rectangular shaped image instead of a single row.
        Mat reconstructionMat = reconstructionRow.reshape(1, faceHeight);// Что здесь происходит и для чего это???
        // Convert the floating-point pixels to regular 8-bit uchar pixels.
        Mat reconstructedFace = Mat(reconstructionMat.size(), CV_8U);// Что здесь происходит и для чего это???
        reconstructionMat.convertTo(reconstructedFace, CV_8U, 1, 0);// Что здесь происходит и для чего это???
        //printMatInfo(reconstructedFace, "reconstructedFace");

        return reconstructedFace;// Это понятно, если все операции прошли нормально возвращаем какоето измененное лицо.. Что мы должны получить на выходе?

    } catch (cv::Exception e) {
        //cout << "WARNING: Missing FaceRecognizer properties." << endl;
        return Mat();// Здесь тоже понятно, если какая либо ошибка возврашаеи пустой Mat.
    }
}

// Verify whether the reconstructed face looks like the preprocessed face, otherwise it is probably an unknown person.
double similarity = getSimilarity(preprocessedFace, reconstructedFace);// Работа этой функции тоже непонятна, ниже вставлю код реализации этой функции. Просьба объяснить как она работает.

double getSimilarity(const Mat A, const Mat B)
{
    if (A.rows > 0 && A.rows == B.rows && A.cols > 0 && A.cols == B.cols) {// Что здесь происходит???
        // Calculate the L2 relative error between the 2 images.
        double errorL2 = norm(A, B, CV_L2);// Что здесь происходит???
        // Convert to a reasonable scale, since L2 error is summed across all pixels of the image.
        double similarity = errorL2 / (double)(A.rows * A.cols);// Что здесь происходит???
        return similarity;
    }
    else {
        //cout << "WARNING: Images have a different size in 'getSimilarity()'." << endl;
        return 100000000.0;  // Return a bad value
    }
}

//Далее понятно
  if (similarity < UNKNOWN_PERSON_THRESHOLD) {.// Если значение схожести изображения в пределах допустимого порога
                    // Identify who the person is in the preprocessed face image.
                    identity = model->predict(preprocessedFace);// Здесь мы получаем дистанцию до ближайшей фотографии в базисе или я не прав???
                    outputStr = toString(identity);
                }
                else {
                    // Since the confidence is low, assume it is an unknown person.
                    outputStr = "Unknown";
                }

///////////// Далее допустим мы перезапускаем программу//////////////////////
//И после перезапуска мы хотим определить лица Петра Петровича Петрова и Ивана Ивановича Иванова;

// Я так понимаю что первым делом мы загружаем ранее сохраненный PCA базис
model->load("C:\\eigen.yml");
// Далее мы сразу переходим в режим распознавания лица MODE_RECOGNITION, не прозодя процесс тренировки то есть режим MODE_TRAINING нам не нужен???
reconstructedFace = reconstructFace(model, preprocessedFace);
//Выясняем на сколько совпадает реконструированное лицо с лицом в текущем кадре
double similarity = getSimilarity(preprocessedFace, reconstructedFace);
// И далее определяем известное это лицо или нет
if (similarity < UNKNOWN_PERSON_THRESHOLD) {.
                    // Identify who the person is in the preprocessed face image.
                    identity = model->predict(preprocessedFace);// Здесь мы получаем дистанцию до ближайшей фотографии в базисе или я не прав???
                    outputStr = toString(identity);
                }
                else {
                    // Since the confidence is low, assume it is an unknown person.
                    outputStr = "Unknown";
                }

А теперь появляются основные вопросы:

1. После перезапуска программы теперь мне надо натренировать базу на новое лицо Сидора Сидоровича. Что мне для этого необходимо сделать? Получить 100 кадров нового лица и пройти процесс тренировки заново? Если я пройду тренировку заново для нового лица, то откуда модель будет брать Массивы лиц "preprocessedFaces" Петра Петровича и Ивана Ивановича, а также присвоенные Массив меток "faceLabeles". Получается я должен был сохранить эти массивы в файл прежде чем перезапускать программу? 

2. И если лиц будет тысяча, это получается каждый раз после перезапуска программы я должен загружать в массив preprocessedFaces всю 1000 лиц и загружать в массив faceLabeles 1000 меток?

Просьба объясните на пальцах дураку. Если можно простыми словами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ух, все перемешали :)

Завтра попробую прояснить, сейчас уже башка не варит..

Одно скажу сейчас, реконструкция тут только для красоты, никакого отношения к процессу сравнения/распознавания она не имеет.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
void Eigenfaces::compute(const vector<Mat>& src, const vector<int>& labels) 
{
    if(src.size() == 0) 
    {
        string error_message = format("Empty training data was given. You'll need more than one sample to learn a model.");
        CV_Error(CV_StsUnsupportedFormat, error_message);
    }
    // Одно изображение - одна строка.
    Mat data = asRowMatrix(src, CV_64FC1);
    // Количество изображений
    int n = data.rows;
    // Размерность данных (ширина на высоту)
    int d = data.cols;
    // Меток столько же сколько фоток (для получения базиса не важно)
    if(n != labels.size()) 
    {
        string error_message = format("The number of samples (src) must equal the number of labels (labels). Was len(samples)=%d, len(labels)=%d.", n, labels.size());
        CV_Error(CV_StsBadArg, error_message);
    }
    // Выберем только несколько собственных осей (с самыми большими собственными числами)
    if((_num_components <= 0) || (_num_components > n))
    {
        _num_components = n;
    }
    // Найдем собственные оси и числа (СОБСТВЕННЫЙ БАЗИС)
    PCA pca(data, Mat(), CV_PCA_DATA_AS_ROW, _num_components);
    // Скопируем их в матрицы
    _mean = pca.mean.reshape(1,1); // Среднее
    _eigenvalues = pca.eigenvalues.clone(); // Собственные числа
    _eigenvectors = transpose(pca.eigenvectors); // Собственные оси
    _labels = labels; // Метки

    // ЗДЕСЬ ВЫЧИСЛЯЮТСЯ КООРДИНАТЫ ЛИЦ В СОБСТВЕНОМ БАЗИСЕ
    for(int sampleIdx = 0; sampleIdx < data.rows; sampleIdx++) 
    {
        Mat p = project(data.row(sampleIdx).clone()); // Многомерная (n-мерная) точка - представляющая лицо в собственном базисе
        this->_projections.push_back(p);
    }
}
void Eigenfaces::predict(const Mat& src, int &minClass, double &minDist) 
{
    if(_projections.empty()) 
   {
        // throw error if no data (or simply return -1?)
        string error_message = "This cv::Eigenfaces model is not computed yet. Did you call cv::Eigenfaces::train?";
        CV_Error(CV_StsError, error_message);
    } else if(_eigenvectors.rows != src.total()) {
        // check data alignment just for clearer exception messages
        string error_message = format("Wrong input image size. Reason: Training and Test images must be of equal size! Expected an image with %d elements, but got %d.", _eigenvectors.rows, src.total());
        CV_Error(CV_StsError, error_message);
    }
    // проецируем новое лицо в собственный базис, теперь оно в тех же координатах что известные нам лица.
    // каждое лицо - n-мерная точка
    Mat q = project(src.reshape(1,1));

	// Если захотим засунуть его в базу просто добавить его в _projections[sampleIdx] и его метку в _labels[sampleIdx].


    // Находим ближайшего соседа из лиц с метками
    minDist = DBL_MAX;
    minClass = -1;
    for(int sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++) {
        double dist = norm(_projections[sampleIdx], q, NORM_L2); // Расстояние
        if((dist < minDist) && (dist < _threshold)) {
            minDist = dist;
            minClass = _labels[sampleIdx]; // Смотрим метку ближайшего соседа (ЭТО РЕЗУЛЬТАТ РАСПОЗНАВАНИЯ)
        }
    }
}

Все!!!! Остальное обычная линейная алгебра.

Код отсюда https://github.com/bytefish/opencv/tree/master/eigenfaces

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо большое за потраченное время и примеры кода. Буду разбираться и тестировать!!! Попробую сравнить качество обнаружения лица из вашего примера с примером из книги Mastering OpenCV. По результатам отпишусь!!! Хороших выходных!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Еще лучше работает комбинация двух методов:

1 О чем и была речь но с чуть "заниженным порогом"

2 Не помню как он называется, там можно взять все кадры из видео распознаваемого лица на них проводится "расчет" и полученному "распознавателю" предъявляются  фотографии из базы прошедшие первый этап.

Ну и опыт показал что без приведение лиц к одному ракурсу и освещению все это вообще не работает(т.е. хотя бы мене 1% по обеим ошибкам)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
13 часа назад, al072 said:

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

Так они и должны быть одинаковы, это один и тот же метод - PCA recognition.

Есть еще Fisher Faces, обычно распознает получше чем PCA, но по смыслу это близкие методы.

Да, LBP работает лучше. 

OpenFace еще лучше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Только жаль она для Web и на JSF, а не на С++.

Читал про более серьезные реализации: OpenCV + ASM AAM или 3d modeling. Кто нибудь пробовал применять на практике?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пробовал AAM, ну не плохо работало, процентов 95 распознавало на ~200 индивидах в базе.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×