Вопрос или проблема
«Специфический код функции выглядит следующим образом. При обработке двух изображений я вызываю эту функцию блоками по 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, может быть вызвана несколькими факторами. Для того чтобы помочь вам решить эту проблему, приведу несколько рекомендаций и объяснений.
Анализ вашей функции
-
Использование
FlannBasedMatcher
:
Вы создаете объектFlannBasedMatcher
внутри функцииAPI_Similar_Sift
. В каждом вызове создается новый экземпляр этого объекта, который будет содержать свои собственные структуры данных и затраты на память. Если вызов происходит в цикле достаточно много раз, это может привести к значительному увеличению использования памяти. - Неэффективное освобождение памяти:
Вы освобождаете дескрипторы и ключевые точки с помощьюclear()
иrelease()
, что хорошо, но возможно, что в результате других операций или при создании объектаFlannBasedMatcher
не вся память очищается должным образом.
Рекомендации по решению проблемы
-
Перемещение 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); ... }
-
Проверка управления памятью в OpenCV:
Убедитесь, что все используемые вами структуры OpenCV корректно очищаются. ХотяMat
в OpenCV автоматически управляет своей памятью, следите за тем, чтобы объектFlannBasedMatcher
не имел дополнительных ресурсов, которые необходимо было бы явно очистить. -
Использование инструмента для обнаружения утечек памяти:
Рекомендуется использовать специальные инструменты для проверки утечек памяти, такие как Valgrind или AddressSanitizer. Это поможет вам точно определить, где происходит утечка, и сосредоточить внимание на соответствующих частях вашего кода. -
Оптимизация работы с дескрипторами:
Проверьте, действительно ли размер дескрипторов, создаваемыхdetectAndCompute
, не превышает ожидаемый. Возможно, стоит использовать параметры (например, установить максимальное число ключевых точек), чтобы убедиться, что размер выходных данных остаётся в пределах разумного. - Обновление библиотек и зависимостей:
Проверьте, обновлён ли OpenCV до последней версии. Иногда проблемы с утечкой памяти связаны с конкретными версиями библиотек, и их обновление может решить проблему.
Итог
Применив приведенные рекомендации и оптимизации, вы должны существенно сократить использование памяти и предотвратить утечки. Дайте знать, если проблема продолжает возникать, и будут нужны дополнительные рекомендации.