我试图从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,以及#34;算法界面&#34;说:
通用算法使用模式已更改:现在必须在包装在智能指针cv :: Ptr中的堆上创建。版本2.4允许直接或通过智能指针进行堆栈和堆分配。
get和set方法已从cv :: Algorithm类中与CV_INIT_ALGORITHM宏一起删除。在3.0中,所有属性都已转换为getProperty / setProperty纯虚拟方法对。因此,无法按名称创建和使用cv :: Algorithm实例(使用通用的Algorithm :: create(String)方法),应该明确调用相应的工厂方法。
这可能意味着无法使用read()和write()函数从XML / YAML文件读取和写入参数。
您能否给我一些例子,说明如何从OpenCV3中的XML / YAML文件中读取Feature Detector算法的参数?
提前致谢!
答案 0 :(得分:1)
如果特定算法会覆盖方法cv::Algorithm::read
和cv::Algorithm::write
,那么您可以按照所述方式使用,例如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...
}