我使用 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()
更新:“除非您打算修改数据,否则不要使用。” (by 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_treasure
内部完全停电。:) 所以为了避免意外修改内部,你需要它。res_handler
m_pirate
m_treasure
m_treasure
clone
另一方面,这个解决方案也有缺陷:
const Mat m_pirate = res_handler.emit_mat();
因为m_treasure
也可以修改,所以m_pirate
后台修改的内容,让盗版的程序员很头疼。:)