什么类型的对象是opencv :: Mat?它是shared_ptr还是auto_ptr?它是指针吗?

时间:2013-06-19 14:11:07

标签: c++ opencv boost stl smart-pointers

我使用的是OpenCv,我在类似下面代码的代码中使用它:

Mat Create()
{ 
     Mat myMat(10, 10, CV8U_C1);    
     int x=myMat.Rows; // I am accessing Mat like an object not a pointer. 
     Return myMat;
 }

 Main()
 {
       Mat aMat=Create(); // created inside this function
       int x=aMat.Rows; // accessing it using . notation
       // do some work
       return;   //I did not delete Mat, as it would release its memory.
 }

如何在我的c ++代码中创建类似的对象?

我正在使用STL,但如果需要,我也可以使用Boost。

3 个答案:

答案 0 :(得分:5)

首先,std::vectorMat和其他数据结构具有析构函数,可在需要时释放底层内存缓冲区。这意味着析构函数不会像Mat那样始终释放缓冲区。他们考虑了可能的数据共享。析构函数递减与矩阵数据缓冲区关联的引用计数器。当且仅当参考计数器达到零时,才释放缓冲区。也就是说,当没有其他结构引用相同的缓冲区时。同样,复制Mat实例时,实际上并未复制实际数据。相反,引用计数器递增以记住存在相同数据的另一个所有者。还有Mat::clone()方法可以创建矩阵数据的完整副本。

答案 1 :(得分:4)

其他答案是正确的 - cv::Mat是一个资源拥有对象,如std::vector<>,可以传递并按值返回。但是,有一种非常重要的方式,cv::Mat表现得像一个指针,这就是它的别名行为。对于大多数类型T,以下情况属实:

T orig = initial_value;
T copy = orig;
mutate(copy);
assert(orig == initial_value);

也就是说,对于大多数类型,副本是独立的。你可以改变一个而不影响另一个。 cv::Mat不是这样。相反,你必须注意这样的事情:

cv::Mat orig = /* ... matrix of all zeros ... */
cv::Mat copy = orig; // NOTE! Creates an alias, not a copy.
copy(2,2) = 42;
assert(orig(2,2) == 42); // Huh.

请参阅?更改副本改变了原来的。从技术上讲,cv::Mat不是常规类型,这很遗憾,因为包括STL在内的大多数现代API都假设类型是常规的。使用cv::Mat,事物会默默地混淆,从而导致难以发现的怪异动作,远距离类型的错误。将cv::Mat极端小心一起使用。并且永远不会使用STL算法和容器。

答案 2 :(得分:0)

只需快速查看API reference

即可回答您的问题
class CV_EXPORTS Mat
{
public:
    // ... a lot of methods ...
    ...

最好的办法是阅读OpenCV tutorial on Mat

  

您需要了解Mat的第一件事是,您不再需要手动分配其内存并在不需要时立即释放它。 ...

     

Mat基本上是一个包含两个数据部分的类:矩阵头(包含矩阵大小,用于存储的方法,存储矩阵的地址等信息)以及指向包含像素值的矩阵......