我经常使用OpenCV C++接口,并设计了一些使用Mat作为私有资源的类。
最近,我对Mat类感到担忧,因为它总是将图像数据用作共享资源,除非我显式调用clone。即使我写const Mat,我也无法确定图像数据不会在外部被更改。
因此,我需要克隆来确保封装性。但需要显式克隆Mat的问题在于,它通常是不必要的和昂贵的。另一方面,我理解共享图像数据的需求源自ROI选择器,并且能够编写类似以下内容的代码:
Mat m_small = m_big(my_roi)
我的问题是:
1.) cv::Mat类是否应该采用惰性克隆? 这样用户将不会从外部看到Mat作为共享资源处理程序。当需要真正的共享图像数据时,用户是否应该显式实例化一个名为SharedMat
的类?
2.) 对于作为类的私有资源的cv::Mat,您是否有任何比始终克隆更好的策略?
更新:“你不使用Mat::clone()
,除非你计划修改数据。”(Vadim Pisarevsky)
这个想法有一个问题。
考虑您拥有这个类的情况:
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_pirate
和 m_treasure
之间的共享图像数据,在 res_handler
内部导致 m_treasure
完全黑屏。所以,为了避免意外修改内部的 m_treasure
,你需要对其进行 clone
。
另一方面,这个解决方案也有缺陷:
const Mat m_pirate = res_handler.emit_mat();
因为m_treasure
也可以被修改,所以m_pirate
的内容会在后台中发生改变,使得海盗的程序员感到很头痛。 :)