Я сталкиваюсь с проблемой утечки памяти при использовании функций FlannMatcher и BFMatcher в C++ OpenCV.

Вопрос или проблема

«Специфический код функции выглядит следующим образом. При обработке двух изображений я вызываю эту функцию блоками по 128×128 пикселей, чтобы вычислить их ключевые точки и сопоставить их. Однако, когда я это делаю, я замечаю, что использование памяти продолжает увеличиваться. Когда я отключаю функцию сопоставления, использование памяти возвращается в норму. Поэтому я полагаю, что проблема заключается в функции сопоставления.

int API_Similar_Sift(void* handle, int x, int y, int blockSizeX, int blockSizeY, int *num1, int *num2, int *matchNum) {
    int result = 0;
    SimilarSiftHandle* h = static_cast<SimilarSiftHandle*>(handle);
    cv::Rect blockRect(x, y, blockSizeX, blockSizeY);
    if (blockRect.x + blockRect.width > h->img1.cols || blockRect.y + blockRect.height > h->img1.rows) {
        return -1; 
    }

    cv::Mat block1 = h->img1(blockRect);
    cv::Mat block2 = h->img2(blockRect);

    h->kp1.clear();
    h->kp2.clear();
    h->des1.release(); 
    h->des2.release(); 

    h->kp1.reserve(h->maxKeypoints);
    h->kp2.reserve(h->maxKeypoints);

    h->akaze->detectAndCompute(block1, cv::noArray(), h->kp1, h->des1);
    h->akaze->detectAndCompute(block2, cv::noArray(), h->kp2, h->des2);

    if (!h->kp1.empty() && !h->kp2.empty())
    {
        h->matches.clear(); 
        if (h->des1.type() == CV_8U) {
            h->des1.convertTo(h->des1, CV_32F);
        }
        if (h->des2.type() == CV_8U) {
            h->des2.convertTo(h->des2, CV_32F);
        }
        cv::flann::IndexParams indexParams; 
        cv::FlannBasedMatcher flannMatcher; 
        flannMatcher.match(h->des1, h->des2, h->matches); 
        flannMatcher.clear();

        *num1 = h->kp1.size();
        *num2 = h->kp2.size();
        *matchNum = h->matches.size();
        result = 1;
    }
    else
    {
        *num1 = h->kp1.size();
        *num2 = h->kp2.size();
        *matchNum = 0;
        result = 0;
    }
    return result;
}

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

Ответ или решение

Проблема утечки памяти, с которой вы столкнулись при использовании функций FlannMatcher и BFMatcher в OpenCV, может быть вызвана несколькими факторами. Для того чтобы помочь вам решить эту проблему, приведу несколько рекомендаций и объяснений.

Анализ вашей функции

  1. Использование FlannBasedMatcher:
    Вы создаете объект FlannBasedMatcher внутри функции API_Similar_Sift. В каждом вызове создается новый экземпляр этого объекта, который будет содержать свои собственные структуры данных и затраты на память. Если вызов происходит в цикле достаточно много раз, это может привести к значительному увеличению использования памяти.

  2. Неэффективное освобождение памяти:
    Вы освобождаете дескрипторы и ключевые точки с помощью clear() и release(), что хорошо, но возможно, что в результате других операций или при создании объекта FlannBasedMatcher не вся память очищается должным образом.

Рекомендации по решению проблемы

  1. Перемещение Matcher за пределы функции:
    Вместо создания нового экземпляра FlannBasedMatcher внутри функции, инициализируйте его один раз вне функции и передавайте его как аргумент в API_Similar_Sift. Это позволит избежать постоянного создания и уничтожения объекта, тем самым снижая вероятность утечек памяти.

    cv::FlannBasedMatcher flannMatcher; // Инициализация вне функции
    
    // модификация функции
    int API_Similar_Sift(void* handle, int x, int y, int blockSizeX, int blockSizeY, int *num1, int *num2, int *matchNum, cv::FlannBasedMatcher &flannMatcher) {
        ...
        flannMatcher.match(h->des1, h->des2, h->matches); 
        ...
    }
  2. Проверка управления памятью в OpenCV:
    Убедитесь, что все используемые вами структуры OpenCV корректно очищаются. Хотя Mat в OpenCV автоматически управляет своей памятью, следите за тем, чтобы объект FlannBasedMatcher не имел дополнительных ресурсов, которые необходимо было бы явно очистить.

  3. Использование инструмента для обнаружения утечек памяти:
    Рекомендуется использовать специальные инструменты для проверки утечек памяти, такие как Valgrind или AddressSanitizer. Это поможет вам точно определить, где происходит утечка, и сосредоточить внимание на соответствующих частях вашего кода.

  4. Оптимизация работы с дескрипторами:
    Проверьте, действительно ли размер дескрипторов, создаваемых detectAndCompute, не превышает ожидаемый. Возможно, стоит использовать параметры (например, установить максимальное число ключевых точек), чтобы убедиться, что размер выходных данных остаётся в пределах разумного.

  5. Обновление библиотек и зависимостей:
    Проверьте, обновлён ли OpenCV до последней версии. Иногда проблемы с утечкой памяти связаны с конкретными версиями библиотек, и их обновление может решить проблему.

Итог

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

Оцените материал
Добавить комментарий

Капча загружается...