【问题标题】:What type of object is a opencv::Mat? It is a shared_ptr or maybe an auto_ptr ? is it a pointer?opencv::Mat 是什么类型的对象?它是 shared_ptr 还是 auto_ptr ?它是一个指针吗?
【发布时间】:2013-06-19 14:11:06
【问题描述】:

我用过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。

【问题讨论】:

  • aMat 仍将被销毁。 (RAII成语)
  • @Magtheridon96 谢谢我知道。我的问题是 Mat 是如何定义的?它是一个shared_pointer吗?当我使用 . ,它不能是指针。那是什么?
  • @mans 这只是一个普通的课程。像这样:class Mat { };
  • @H2CO3 所以当我将它从一个函数传递到另一个函数时,它会被复制过来吗?那将是非常低效的,opencv 应该非常慢。
  • @JBL 那是什么?普通班?

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


【解决方案1】:

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

【讨论】:

  • 谢谢。是否可以编写一个基类,当我的类从它继承时,它会为我进行引用计数并以我可以释放分配的内存的方式调用虚函数?
【解决方案2】:

其他答案是正确的——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 算法和容器。

【讨论】:

  • 感谢您的提醒,我想知道这一点。有没有办法找出cv::Mat 上的哪些操作导致它被复制?
  • 按值传递并返回 vector<T> 是错误的。
【解决方案3】:

只需快速查看API reference,即可回答您的问题

class CV_EXPORTS Mat
{
public:
    // ... a lot of methods ...
    ...

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

关于 Mat 你首先需要知道的是,你不再需要手动分配它的内存,并在你不需要它时立即释放它。 ...

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-16
    • 2017-03-05
    • 2012-11-11
    • 2013-10-28
    • 2012-04-01
    • 2013-03-31
    • 1970-01-01
    相关资源
    最近更新 更多