【问题标题】:Mat class in OpenCV (c++)OpenCV 中的 Mat 类(c++)
【发布时间】:2019-03-10 09:21:22
【问题描述】:

根据opencv文档Mat类被描述为:Mat基本上是一个有两个数据部分的类:矩阵头(包含矩阵的大小,用于存储的方法,地址是存储的矩阵,等等)指向包含像素值的矩阵的指针

有人可以帮助了解该标头是什么以及类是如何声明的吗?

【问题讨论】:

  • OpenCV 是开源项目,你有没有尝试看一下源代码?
  • 我相信为cv::Mat类提供了相当全面的documentation。
  • @Aniruddha 是我投了反对票。不要指责人们凭你的印象猜测。请解释一下我具体提到的文档中你不明白的地方。
  • @πάνταῥεῖ 你能帮忙解释一下哪个部分是标题吗?
  • 基于来源here,我没有看到任何成员被标记或明确描述为“标题”。你能提供这句话的背景吗?

标签: c++ opencv


【解决方案1】:

根据OpenCV 2.4.xxx:

Mat基本上是a class with two data parts:the matrix header(包含矩阵的大小、存储的方法、存储的矩阵在哪个地址等信息)和a pointer to the matrix containing the pixel values(取任何维度取决于选择的存储方法)。 matrix header size is constant,但是矩阵本身的大小可能因图像而异,通常会大几个数量级。

一个简单的公式:a Mat object = the matrix header + the matrix data pointer。

好的,什么是矩阵数据指针?指向矩阵数据的是uchar* data。

然后cv::Mat 中的所有其他人都称为matrix header。

两部分有什么好处?我们可以对矩阵进行浅拷贝,并使用引用计数器进行内存管理。至于reference counter(counting),是编程中的一个重要话题。来自维基reference counter(counting):In computer science, reference counting is a technique of storing the number of references, pointers, or handles to a resource such as an object, block of memory, disk space or other resource.


cv::Mat 中有两个重要功能供您可能感兴趣的参考计数器使用:

void cv::Mat::addref() and void cv::Mat::release()

/** @brief Increments the reference counter.
The method increments the reference counter associated with the matrix data. If the matrix header
points to an external data set (see Mat::Mat ), the reference counter is NULL, and the method has no
effect in this case. Normally, to avoid memory leaks, the method should not be called explicitly. It
is called implicitly by the matrix assignment operator. The reference counter increment is an atomic
operation on the platforms that support it. Thus, it is safe to operate on the same matrices
asynchronously in different threads.
 */
void addref();

/** @brief Decrements the reference counter and deallocates the matrix if needed.
The method decrements the reference counter associated with the matrix data. When the reference
counter reaches 0, the matrix data is deallocated and the data and the reference counter pointers
are set to NULL's. If the matrix header points to an external data set (see Mat::Mat ), the
reference counter is NULL, and the method has no effect in this case.
This method can be called manually to force the matrix data deallocation. But since this method is
automatically called in the destructor, or by any other method that changes the data pointer, it is
usually not needed. The reference counter decrement and check for 0 is an atomic operation on the
platforms that support it. Thus, it is safe to operate on the same matrices asynchronously in
different threads.
 */
void release();

当然,也许你只需要注意:

cv::Mat a = cv::Mat::zeros(2,2,CV_8UC1);
cv::Mat b,c;

b = a;       // shallow copy, share the same matrix data by the data pointer
a.copyTo(c); // deep copy, allocate matrix data memory, and assign the new pointer 

一个演示:

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main(){
    cv::Mat a = cv::Mat::zeros(2,2,CV_8UC1);
    cv::Mat b,c;

    b = a;       // shallow copy, share the same matrix data pointer
    a.copyTo(c); // deep copy, allocate matrix data memory, and assign the new pointer

    std::cout << "----- a -----\n" << a << "\n----- b -----\n" << b << "\n----- c -----\n" << c << std::endl;


    std::cout << "\nModify a, b, c:\n";
    a.at<unsigned char>(0,0) = 1; // a, b share the same matrix data
    b.at<unsigned char>(1,0) = 2;
    c.at<unsigned char>(1,1) = 3; // c has independent matrix data

    std::cout << "----- a -----\n" << a << "\n----- b -----\n" << b << "\n----- c -----\n" << c << std::endl;


    return 0;

}

结果:

----- a -----
[  0,   0;
   0,   0]
----- b -----
[  0,   0;
   0,   0]
----- c -----
[  0,   0;
   0,   0]

Modify a, b, c:
----- a -----
[  1,   0;
   2,   0]
----- b -----
[  1,   0;
   2,   0]
----- c -----
[  0,   0;
   0,   3]

【讨论】:

  • 非常感谢您的解释和努力。我希望你继续帮助人们。
  • 如果值得,我会伸出援助之手。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-28
  • 1970-01-01
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多