我正在开发一个使用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
的正确程度如何?它如何影响整体性能(特别是在内存中)?我非常感谢对此问题的任何见解。
答案 0 :(得分:2)
发布提示显示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);
正如您所见,不需要临时图像。