Ответ 1
Чтобы понять, что происходит, вам нужно взглянуть на конструкторы С++, более конкретно конструктор копирования.
Когда вы создаете cv::Mat
из другого cv::Mat
, как в:
cv::Mat a = cv::imread("huge.png", 1);
cv::Mat b = a;
для выполнения копии объекта вызывается конструктор копирования (который является функцией) cv::Mat
. Прежде чем говорить о том, что происходит в процедуре копирования, вы должны понимать, что, поскольку cv::Mat
используется для хранения изображений, большие изображения могут занимать сотни мегабайт в памяти. Итак, что делает конструктор cv::Mat
в приведенном выше примере, скопируйте весь заголовок (высота, ширина, информация о глубине и другие) a
в b
, но вместо копирования целые данные/пиксели a
(которые могут быть сотнями МБ), он просто указывает (используя указатель) на исходные данные a
.
Другими словами, не копирование всех данных изображения является решением оптимизации/производительности.
Теперь рассмотрим этот код, который вызывает функцию и передает cv::Mat
в качестве параметра:
void do_something(cv::Mat src)
{
// changing src pixels will be the same as changing orig pixels
}
int main()
{
cv::Mat orig = cv::imread("huge.png", 1);
do_something(orig);
return 0;
}
Если вы изучили, как передавать параметры в функции, вы знаете, что вызов do_something(a);
будет передать параметр по значению. Это означает, что он попытается скопировать содержимое orig
в src
, однако эта процедура активирует конструктор копирования cv::Mat
, который не будет делать жесткую копию данных, как я только что объяснил.
Решение этой проблемы? Если вы пишете do_something()
и хотите просто сделать реальную копию orig
, просто создайте новый cv::Mat
и вызовите метод copyTo()
:
void do_something(cv::Mat src)
{
cv::Mat real_copy = src.copyTo();
// operating on the data of real_copy will not affect orig
}
Но помните, если src
составляет ~ 100 МБ, вызывая copyTo()
, чтобы реальная копия занимала еще одну ~ 100 МБ памяти, а это означает, что в одной функции вы можете перейти от 100 МБ до 200 МБ. Помните об этом при разработке вашей системы. Удачи.