简体   繁体   English

OpenCV(C ++)中的Mat类

[英]Mat class in OpenCV (c++)

As per opencv documentation Mat class is described as: Mat is basically a class with two data parts: the matrix header (containing information such as the size of the matrix, the method used for storing, at which address is the matrix stored, and so on) a pointer to the matrix containing the pixel values 根据opencv文档,Mat类的描述如下: Mat本质上是一个具有两个数据部分的类:矩阵标头(包含诸如矩阵大小,存储方法,存储矩阵的地址等信息)。 on)指向包含像素值的矩阵的指针

Could someone help understand what is that header and how is the class declared? 有人可以帮助您了解该标头是什么以及如何声明该类吗?

According to OpenCV 2.4.xxx : 根据OpenCV 2.4.xxx

Mat is basically a class with two data parts : the matrix header (containing information such as the size of the matrix, the method used for storing, at which address is the matrix stored, and so on) and a pointer to the matrix containing the pixel values (taking any dimensionality depending on the method chosen for storing) . Mata class with two data partsthe matrix header (包含诸如矩阵大小,存储方法,存储矩阵的地址等信息)以及a pointer to the matrix containing the pixel values (根据选择的存储方法采用任何尺寸)。 The matrix header size is constant , however the size of the matrix itself may vary from image to image and usually is larger by orders of magnitude. matrix header size is constant ,但是矩阵本身的大小可能因图像而异,通常会增加几个数量级。

A simple formular: a Mat object = the matrix header + the matrix data pointer . 一个简单的公式: a Mat object = the matrix header + the matrix data pointer

Ok, what is the matrix data pointer? 好的,矩阵数据指针是什么? It is uchar* data , that points to the matrix data. uchar* data指向矩阵数据。

Then all others in cv::Mat called matrix header . 然后cv::Mat所有其他对象称为matrix header

What is the advantage of two parts? 两部分的优点是什么? We can do shallow copy of a matrix, and use reference counter for memory management. 我们可以对矩阵进行浅表复制,并使用引用计数器进行内存管理。 As for reference counter(counting) , it's an important topic in programming. 至于引用计数器(计数) ,这是编程中的重要主题。 From wiki 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. 来自Wiki 参考计数器(计数)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.


There are two important function in cv::Mat for reference counter you maybe interested in: cv::Mat有两个重要的功能,您可能cv::Mat参考计数器感兴趣:

void cv::Mat::addref() and void cv::Mat::release() 无效cv :: Mat :: addref()和无效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();

Of course, maybe you just need to notice: 当然,也许您只需要注意:

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 

A demo : 演示:

#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;

}

The result: 结果:

----- 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]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM