embeddedなブログ

組み込みシステムに関することや趣味に関することをダラダラと書いていきます(^^)

YAML形式のファイルを読み込む方法 (Visual Studio 2019)

2021-06-06 13:50:58 | Windows Embedded Standard

プログラムの設定ファイルとしてYAML形式のファイルが良さそうかなと思ったのですが、読み込みの実装方法を調べてみました。GitHubにいろいろと独自のライブラリが公開されているのですが、何とOpenCVで簡単に実現が出来たのですね。全然知らなくて、こんな身近な方法で実現出来るとは驚きました。

簡単にサンプル的な実装をしたので、ソースコードをご紹介します。環境はWindows上でVisual Studio 2019を用いています。
ソースコードは以下のような感じです。

#include <iostream>
#include <string>
#include <filesystem>
#include <vector>
#include "boost/program_options.hpp"
#include "opencv2/core.hpp"
namespace fs = std::filesystem;
namespace po = boost::program_options;

int main (int argc, char** argv)
{
    po::options_description opt("Options");
    opt.add_options()
	    ("help,h", "Help")
	    ("conf", po::value<std::string>(), "Configuration file path");
    po::variables_map vm;
    try
    {
	    po::store(po::parse_command_line(argc, argv, opt), vm);
    }
    catch (const boost::program_options::error_with_option_name& e)
    {
	    std::cout << e.what() << std::endl;
    }
    po::notify(vm);

    if (vm.count("help"))
    {
	    std::cout << opt << std::endl;
	    exit(-1);
    }
    // YAMLファイルへのパスを引数から取得する
    const std::string config_filename = vm["conf"].as<std::string>();
    std::cout << "Reading: " << config_filename << std::endl;

    // YAMLファイルを読み込むためのFileStorageインスタンスを生成
    cv::FileStorage fs;
    // YAMLファイルの読み込み
    fs.open(config_filename, cv::FileStorage::Mode::READ | cv::FileStorage::Mode::FORMAT_YAML, "Shift_JIS");
    if (!fs.isOpened())
    {
        std::cerr << "Failed to open " << config_filename << std::endl;
        return -1;
    }

    // count を取得
    int count;
	fs["count"] >> count;
    std::cout << "count " << count << std::endl;

    // images を取得
    cv::FileNode n = fs["images"];
    if (n.type() != cv::FileNode::SEQ)
    {
        std::cerr << "images is not a sequence!" << std::endl;
        return -1;
    }
    // 取得したimagesの要素をvectorに格納
    std::vector<std::string> images;
    cv::FileNodeIterator it = n.begin(), it_end = n.end();
    for (; it != it_end; ++it) {
        images.emplace_back((std::string)*it);
    }
    for (auto img : images) {
        std::cout << "image " << img << std::endl;
    }

    // parameters のparam1とparam2を取得
    int param1, param2;
    n = fs["parameters"];
    n["param1"] >> param1;
    n["param2"] >> param2;
    std::cout << "param1  " << param1 << std::endl;
    std::cout << "param2  " << param2 << std::endl;

    // Mat型のrotationとtranslationを取得
    cv::Mat R, T;
    fs["rotation"] >> R;
    fs["translation"] >> T;
    std::cout << "rotation = " << R << std::endl;
    std::cout << "translation = " << T << std::endl;

    return 0;
}

 

今回の実験用に用意したYAMLファイルの中身は下記です。

 

%YAML:1.0
count: 1000
images:
   - "DSC0001.jpg"
   - "DSC0002.jpg"
   - "DSC0003.jpg"
parameters:
   param1: 1
   param2: 2
rotation: # Rotation Matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ]
translation: # Translation Vector
   rows: 3
   cols: 1
   dt: d
   data: [ 0.0, 0.0, 0.0 ]

 

 


最新の画像もっと見る