Я много работаю с интерфейсом OpenCV С++ и разработал ряд классов, которые используют Mat как частные ресурсы.
В последнее время меня беспокоил класс Mat, поскольку он всегда использует данные изображения в качестве общего ресурса, если я явно не вызываю clone. Даже если я пишу const Mat
, я не могу быть уверен, что imagedata не будет изменяться позже извне.
Поэтому мне нужно клонировать, чтобы обеспечить инкапсуляцию. Но проблема с необходимостью явного клонирования Mat заключается в том, что он часто бывает ненужным и дорогостоящим. С другой стороны, я понимаю, что потребность в общих изображениях возникает из селекторов roi и может написать что-то вроде этого:
Mat m_small = m_big(my_roi)
.
Мои вопросы:
1.) Разве класс cv:: Mat не будет клонирован лениво?. Таким образом, пользователь не увидит Mat как общие обработчики ресурсов извне. Должен ли пользователь явно создавать экземпляр класса, называемого как SharedMat
, когда требуется реальная общая информация?
2.) У вас есть стратегия лучше, чем всегда клонирование в случае cv:: Mat как частный ресурс для класса?
UPDATE: "вы не используете Mat::clone()
, если вы не планируете изменять данные". (Вадим Писаревский)
У этой идеи есть проблема.
Рассмотрим ситуацию, когда у вас есть этот класс:
class Res_handler{
public:
const Mat emit_mat(){ return m_treasure; } // I argue you are compelled to clone here.
private:
Mat m_treasure;
};
Если вы не clone
, в этом случае вы можете написать
Mat m_pirate = res_handler.emit_mat(); m_pirate = Scalar(0,0,0);
что приводит к полному отключению в m_treasure
внутри res_handler
через данные общего изображения между m_pirate
и m_treasure
.:) Поэтому, чтобы избежать случайной модификации внутреннего m_treasure
, вам нужно clone
его.
С другой стороны, это решение также ошибочно:
const Mat m_pirate = res_handler.emit_mat();
потому что m_treasure
тоже может быть изменен, поэтому содержимое m_pirate
изменяется в фоновом режиме, вызывая сильную головную боль для пиратского программиста.:)