Работа OpenCV с src, dst Mat и распределение памяти [дубликат]

Объяснение C ++.

Подумайте о интерфейсе как об общедоступных методах классов.

Затем вы могли бы создать шаблон, который «зависит» от этих общедоступных методов, чтобы выполнить его (он выполняет вызовы функций, определенные в открытом интерфейсе классов). Предположим, что этот шаблон является контейнером, таким как векторный класс, и интерфейс, от которого он зависит, является алгоритмом поиска.

Любой класс алгоритмов, который определяет функции / интерфейс Vector, вызывает вызовы, которые удовлетворяют «контракту», (как объяснил кто-то в первоначальном ответе). Алгоритмы даже не должны быть одного базового класса; единственное требование состоит в том, что функции / методы, которые вектор зависит от (интерфейса), определены в вашем алгоритме.

Точка всего этого заключается в том, что вы могли бы предоставить любой другой алгоритм поиска / класс так же долго поскольку он предоставил интерфейс, от которого зависит вектор (поиск пузырьков, последовательный поиск, быстрый поиск).

Возможно, вам также захочется спроектировать другие контейнеры (списки, очереди), которые будут использовать тот же алгоритм поиска, что и Vector by если они выполняют интерфейс / контракт, на которые зависят ваши алгоритмы поиска.

Это экономит время (повторное использование кода ООП), так как вы можете написать алгоритм один раз, а не снова и снова, каждый новый объект, который вы создаете, без чрезмерного усложнения проблемы с заросшим деревом наследования.

Что касается «отсутствия» в отношении того, как все работает; (по крайней мере, на C ++), так как это работает в основном из стандартной среды библиотеки TEMPLATE.

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

Это огромная тема и один из краеугольных принципов дизайна шаблонов.

5
задан jeff 6 October 2015 в 16:38
поделиться

2 ответа

Да, в OpenCV это безопасно.


Внутренне функция, подобная:

void somefunction(InputArray _src, OutputArray _dst);

, сделает что-то вроде:

Mat src = _src.getMat();
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();

// dst filled with values

Итак, если src и dst:

  • одно и то же изображение create фактически ничего не сделает, а модификации эффективно на месте . Некоторые функции могут clone отображать src внутри, если операция не может быть на месте (например, findConturs в OpenCV> 3.2), чтобы гарантировать правильное поведение.
  • разные изображения, create создайте новую матрицу dst без изменения src.

В документации указано, что это поведение по умолчанию не выполняется.

Примечательным примером является findContours, которые изменяют матрицу src. Вы справляетесь с этим, обычно проходя src.clone() во входе, так что изменяется только клонированная матрица, но не та, которую вы клонировали.

Из OpenCV 3.2, findContours не изменяет входное изображение .


Благодаря Фернандо Бертольди для рассмотрения ответа

8
ответ дан Community 21 August 2018 в 20:41
поделиться
  • 1
    Спасибо, я приму это как можно скорее. Однако теперь я получаю ошибку, подобную этой: stackoverflow.com/questions/17785028/… . Считаете ли вы, что есть исключения, чтобы это было безопасно? – jeff 6 October 2015 в 16:42
  • 2
    @halilpazarlama, да. есть исключения, но они документированы (см. обновленный ответ). Эта новая ошибка, вызванная, вероятно, отсутствием заголовков или библиотек (см. Ответ в этом вопросе). – Miki 6 October 2015 в 16:46
  • 3
    @Miki на самом деле src и dst в конечном итоге указывают на тот же блок памяти, поэтому ваш ответ неверен. Поскольку форма и тип совпадают, новая память не выделяется. См. Документацию для create. – Fernando Bertoldi 19 January 2017 в 18:07
  • 4
    @FernandoBertoldi Я не знаю, почему я написал это дерьмо :). Вы, очевидно, правы. Тем не менее, в OpenCV это safe для этого. Спасибо за указание на это. – Miki 19 January 2017 в 18:23
  • 5
    @Miki, что вы приветствуете :) Ответьте, что это безопасно, это зависит от операции, и проблема в том, что документация не всегда ясно, безопасна она или нет. Например, очевидно, что это безопасно с cv::threshold, поскольку в источнике OpenCV есть примеры, которые используют тот же аргумент для src и dst. – Fernando Bertoldi 19 January 2017 в 18:49

EDIT: Теперь, когда вопрос был обновлен, я понимаю, что это не имеет никакого отношения. Однако я оставлю его здесь, если кто-то ищет подходящую проблему.


В целом с C ++, насколько безопасна эта ситуация, действительно зависит от тела рассматриваемой функции , Если вы читаете и записываете одну и ту же переменную напрямую, вы можете столкнуться с некоторыми серьезными логическими проблемами.

Однако, если вы используете временную переменную для хранения исходного значения перед ее перезаписью, это должно быть хорошо.

МАССИВНОЕ слово предупреждения, если вы работаете с массивами, Однако. Если вы пытаетесь сохранить все содержимое массива во временной переменной, вы должны быть осторожны, вы храните фактический массив, а не только указатель на него. Во многих ситуациях было бы целесообразно сохранять отдельные значения в массиве временно (например, в функции свопинга). Однако я не могу дать больше дальнейших рекомендаций в этом отношении, поскольку все зависит от того, что вы пытаетесь сделать.

Короче говоря, все зависит от реализации вашей функции.

2
ответ дан CodeMouse92 21 August 2018 в 20:41
поделиться
  • 1
    Вы правы, и да, я только просил функции OpenCV. Значит, я в безопасности? :) – jeff 6 October 2015 в 16:41
  • 2
    Я бы догадался. Основываясь на ответе Мики, разработчики OpenCV учли эту логику, когда они написали свой код, так что вы хороши. – CodeMouse92 6 October 2015 в 16:42
Другие вопросы по тегам:

Похожие вопросы: