我使用的是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。
答案 0 :(得分:5)
首先,std::vector
,Mat
和其他数据结构具有析构函数,可在需要时释放底层内存缓冲区。这意味着析构函数不会像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基本上是一个包含两个数据部分的类:矩阵头(包含矩阵大小,用于存储的方法,存储矩阵的地址等信息)以及指向包含像素值的矩阵......