Я использую оболочку Java OpenCV JNA.
Я использую много преобразований OpenCV, где мне нужно предоставить коврики src и dst, например:
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGB2GRAY);
Imgproc.adaptiveThreshold(mat, mat, 255, Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C, Imgproc.THRESH_BINARY, 121, 13);
Как видите, я использую тот же экземпляр mat, что и src и dst.
Рекомендуется ли использовать тот же экземпляр, что и src и dst, или это приведет к утечке памяти?
Как это работает под капотом? Заменяет ли он старую память mat новым результатом преобразования или такая операция выделяет новую память для dst и возвращает указатель на нее, не освобождая память, выделенную ранее для src, что приводит к проблеме утечки памяти?
Я столкнулся с проблемой утечки памяти в моем приложении, и я подозреваю, что причиной этого может быть неправильное использование операций OpenCV, и вот почему я хотел бы знать, как это работает под капотом.
Это полностью в области возможностей. К сожалению, я никогда не работал с OpenCV под Java, поэтому я не могу рассказать вам больше, кроме того, что он работает для большинства операций, но может создавать проблемы. Насколько мне известно, это, например, не работает для фильтра biliteralBlur. Вероятно, это не самый чистый способ сделать это, давайте продолжим.
В cvtColor это бесполезно, поскольку вы меняете количество каналов, поэтому вы все время будете перераспределять их. Поскольку cv::Mat (базовая реализация) выполняет подсчет ссылок, утечек не должно происходить. Обычно в документации упоминается, работает ли он на месте или нет - например, adaptiveThreshold: «Функция может обрабатывать изображение на месте». Повторное использование одного и того же экземпляра Mat (постоянного размера и типа), особенно между итерациями, весьма полезно - вы избегаете дорогостоящих распределений и уменьшаете скорость фрагментации адресного пространства (важно для 32-битной версии).




В большинстве случаев это не проблема. Насколько мне известно, есть пара исключений, когда это может привести к сообщению об ошибке, но в целом это, по крайней мере, работает. К сожалению, я не смог найти ничего в документации OpenCV по этому поводу.