我正在开发一个使用 OpenCV FileStorage API 持续加载和释放 OpenCV 矩阵的系统。这些矩阵保存图像特征描述符。具体来说,完成这项工作的代码是这样的:
descriptors.create(rows, cols, type);
...
for (cv::FileNodeIterator it = keypointsSequence.begin(); it != keypointsSequence.end(); it++, idx++) {
...
cv::Mat featureVector;
(*it)["descriptor"] >> featureVector;
featureVector.copyTo(descriptors.row(idx));
featureVector.release();
}
据我了解 this post cv::Mat
仅在使用 Mat::create
创建时才会被释放。尽管我使用的是 create 方法,但其内容是从加载的矩阵中复制的。
我有几个问题:
featureVector
是否已正确释放并因此释放其内存?还是我必须手动删除它?- 在循环内定义
featureVector
的正确性如何?它如何影响整体性能(特别是内存)?
如果您对这个问题有任何见解,我将不胜感激。
最佳答案
您提到的帖子展示了如何“可以”手动释放 Mat,但这并不意味着您“需要”自己释放它。 Mat 是一个智能指针,可以自行处理各种类型的释放。就我个人而言,我自己从来不需要使用发布函数(而且我已经使用 OpenCV 多年了)。
仅当其大小发生更改时,它才会重新分配内存。但事实并非如此。因此,在循环外部定义它可以防止大量不必要的分配和释放。
此外,为什么要使用临时Mat(featureVector)而不是直接写入descriptors.row(idx)?
编辑(回复评论3):
你的错误看起来很奇怪。为了确保代码正常工作,我编写了非常短的测试代码,并且它按预期工作。这是:
Mat src = imread(argv[1],-1);
FileStorage fs("test.yml", FileStorage::WRITE);
fs << "imgs" << "[" << "{" << "img" << src.row(500) << "}" << "]";
fs.release();
FileStorage fs2("test.yml", FileStorage::READ);
Mat src2(src.size(), src.type(), Scalar(0));
FileNode imgsNode= fs2["imgs"];
for(FileNodeIterator it = imgsNode.begin(); it != imgsNode.end(); ++it )
(*it)["img"] >> src2.row(500);
fs2.release();
imwrite("res.pgm",src2);
如您所见,不需要临时图像。
关于c++ - 使用 FileStorage API 加载的 cv::Mat 的可用内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20062229/