Как добавить метод в неуправляемый код в проекте FaceRecognition - PullRequest
0 голосов
/ 05 января 2019

Я реализую небольшую программу FaceRecognition, используя Emgu в качестве оболочки библиотек OpenCV. Кажется, это работает нормально, но мне нужна функция, которая возвращает все расстояния между образцом изображения и лицами в базе данных (реализованный метод FaceRecognizer.Predict возвращает только наименьшее расстояние и метку).

Итак, я построил Emgu из Git, чтобы адаптировать функции в неуправляемом коде (cvextern.dll) к своим потребностям.

Вот оригинал в face_c.cpp

void cveFaceRecognizerPredict(cv::face::FaceRecognizer* recognizer, cv::_InputArray* image, int* label, double* dist)
{ 
    int l = -1;
    double d = -1; 
    recognizer->predict(*image, l, d); 
    *label = l; 
    *dist = d; 
}

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

Метод, который я написал после резюме в opencv face.hpp:

void cveFaceRecognizerPredictCollector(cv::face::FaceRecognizer * recognizer, cv::_InputArray * image, std::vector<int>* labels, std::vector<double>* distances)
{
    std::map<int, double> result_map = std::map<int, double>();
    cv::Ptr<cv::face::StandardCollector> collector = cv::face::StandardCollector::create();

    recognizer->predict(*image, collector);

    result_map = collector->getResultsMap();

    for (std::map<int, double>::iterator it = result_map.begin(); it != result_map.end(); ++it) {
        distances->push_back(it->second);
        labels->push_back(it->first);
    }
}

и звонилка в c #

using (Emgu.CV.Util.VectorOfInt labels = new Emgu.CV.Util.VectorOfInt())
using (Emgu.CV.Util.VectorOfDouble distances = new Emgu.CV.Util.VectorOfDouble())
using (InputArray iaImage = image.GetInputArray())
{
    FaceInvoke.cveFaceRecognizerPredictCollector(_ptr, iaImage, labels, distances);
}

[DllImport(CvInvoke.ExternLibrary, CallingConvention = CvInvoke.CvCallingConvention)]
internal extern static void cveFaceRecognizerPredictCollector(IntPtr recognizer, IntPtr image, IntPtr labels, IntPtr distances);

Приложение работает в режиме реального времени, поэтому функция в c # вызывается непрерывно. В моей базе данных хранятся только два лица и одна метка (один и тот же человек), поэтому первый вызов правильно возвращает единственно возможную метку и сохраняет ее в labels. Поддерживая работоспособность приложения, возвращаемые метки и размер labels вектора продолжают расти, заполненные незарегистрированными метками, которые я не знаю, где он берет. Мне кажется, что сборщик в c ++ не имеет хороших ссылок, поэтому каждый раз, когда вызывается функция, она сохраняет данные, не освобождая предыдущие, перезаписывая их. Но это только мое предположение, я не очень хорош с C ++.

Что еще может быть не так?

Надеюсь, вы можете помочь

...