我正在尝试从 OpenCV3 中的 YAML 文件中读取特征检测器(例如:SIFT)的参数。
我正在尝试使用 Documentation 中的提议代码.但它根本不编译。所以,我让它编译,稍微改变一下
#include "opencv2/opencv.hpp"
#include <opencv2/core/persistence.hpp>
#include "opencv2/xfeatures2d.hpp"
using namespace cv::xfeatures2d;
int main () {
cv::Ptr<cv::Feature2D> surf = SURF::create();
cv::FileStorage fs("../surf_params.yaml", cv::FileStorage::WRITE);
if( fs.isOpened() ) // if we have file with parameters, read them
{
std::cout << "reading parameters" << std::endl;
surf->read(fs["surf_params"]);
}
else // else modify the parameters and store them; user can later edit the file to use different parameters
{
std::cout << "writing parameters" << std::endl;
cv::Ptr<cv::xfeatures2d::SURF> aux_ptr;
aux_ptr = surf.dynamicCast<cv::xfeatures2d::SURF>();
aux_ptr->setNOctaves(3); // lower the contrast threshold, compared to the default value
{
cv::internal::WriteStructContext ws(fs, "surf_params", CV_NODE_MAP);
aux_ptr->write(fs);
}
}
fs.release();
// cv::Mat image = cv::imread("myimage.png", 0), descriptors;
// std::vector<cv::KeyPoint> keypoints;
// sift->detectAndCompute(image, cv::noArray(), keypoints, descriptors);
return 0;
}
但是根本没有读取或写入参数。
我也检查了这个Transition Guide ,并在“算法接口(interface)”部分说:
General algorithm usage pattern has changed: now it must be created on heap wrapped in smart pointer cv::Ptr. Version 2.4 allowed both stack and heap allocations, directly or via smart pointer.
get and set methods have been removed from the cv::Algorithm class along with CV_INIT_ALGORITHM macro. In 3.0 all properties have been converted to the pairs of getProperty/setProperty pure virtual methods. As a result it is not possible to create and use cv::Algorithm instance by name (using generic Algorithm::create(String) method), one should call corresponding factory method explicitly.
也许这意味着无法使用 read() 和 write() 函数从 XML/YAML 文件读取和写入参数。
您能给我一些示例,说明如何在 OpenCV3 中从 XML/YAML 文件中读取特征检测器算法的参数吗?
提前致谢!
最佳答案
如果特定算法重写方法cv::Algorithm::read
和cv::Algorithm::write
,那么您可以按照描述使用 then,例如, here .
但是,cv::xfeatures2d::SURF
不会覆盖这些方法,因此您不能使用这种方法。
但是,您可以将需要修改的属性存储在 FileStorage
中,照常读写它们,然后修改 SURF
对象:
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include <iostream>
int main()
{
cv::Ptr<cv::Feature2D> surf = cv::xfeatures2d::SURF::create();
{
// Try to read from file
cv::FileStorage fs("surf_params.yaml", cv::FileStorage::READ);
if (fs.isOpened())
{
std::cout << "reading parameters" << std::endl;
// Read the parameters
int nOctaves = fs["nOctaves"];
surf.dynamicCast<cv::xfeatures2d::SURF>()->setNOctaves(nOctaves);
}
else
{
// Close the file in READ mode
fs.release();
// Open the file in WRITE mode
cv::FileStorage fs("surf_params.yaml", cv::FileStorage::WRITE);
std::cout << "writing parameters" << std::endl;
fs << "nOctaves" << 3;
// fs in WRITE mode automatically released
}
// fs in READ mode automatically released
}
}
您可以使 surf
对象成为指向 cv::xfeatures2d::SURF
的指针以避免强制转换:
cv::Ptr<cv::xfeatures2d::SURF> surf = ...
如果您需要支持不同的Features2D
,您还可以在FileStorage
中存储特定功能的标识符,例如:
fs << "Type" << "SURF";
然后有条件地读取选项以恢复其属性:
string type;
FileNode fn_type = fs.root();
type = fn_type["Type"];
if(type == "SURF") {
// Read SURF properties...
} else if(type == "SIFT") {
// Read SIFT properties...
}
关于c++ - OpenCV3中如何从xml/yml文件中读写算法参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36156386/