c++ - OpenCV3中如何从xml/yml文件中读写算法参数

标签 c++ xml opencv yaml opencv3.0

我正在尝试从 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::readcv::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/

相关文章:

c++ - 使用 Boost property_tree 读取 JSON

c++ - 具有 mkl 后端的特征库的系数数组操作的性能

java - 增量/流式 XSLT 转换?

ruby-on-rails - 使用 Devise 对身份验证失败的自定义 XML 响应

c - 如何将图像切片/切割成碎片

c++ - Qt QGraphicsScene 添加项目缓慢

c++ - 两个数组,整数和字符串,如何显示带有相应整数的字符串?

java - 是否有单个 XPath 表达式可用于在 CDATA 部分中导航 XML?

c++ - 如何创建特征向量以使用 open cv 识别字符

.net - 如何在 C++ 中将 std::string 转换为 CV::String?