picojson使用说明


前言

通常c++解析json会使用jsoncpp,使用起来也很方便,但是需要引入几个源文件。
如果你不希望引入源文件或第三方库,那么picojson就是一个比较好的选择,因为它只有一个头文件。


最近yolov5后处理加载中用到了picojson加载和保存json文件

读取

{ #json
  "post_params": {
    "prob_threshhold": 0.35,
    "nms_threshhold": 0.45,
    "anchors": [25.015625, 51.40625, 56.1875, 26.359375, 61.03125, 57.5625, 124.625, 43.15625, 59.6875, 110.0625, 139.5, 75.5625, 113.375, 173.75, 270.25, 89.9375, 268.5, 245.875],
    "class_names":["fish"]
  }
}
std::string load_file(const std::string& path) {
    std::ifstream ifs(path);
    if (!ifs.is_open() || ifs.fail()) {
        fprintf(stderr, "Read image failed.\n");
        return "";
    }
    return std::string((std::istreambuf_iterator<char>(ifs)),
                  (std::istreambuf_iterator<char>()));
}

ObjectPostParams parse_post_params(const std::string& fn) {
    try {
        picojson::value v;
        auto err = picojson::parse(v, load_file(fn));
        if (!err.empty()) throw std::runtime_error(err);

        ObjectPostParams pp;
        for (auto& obj_itr: v.get<picojson::object>()) {
            auto& vobj = obj_itr.second.get<picojson::object>();
            pp.prob_threshhold = vobj["prob_threshhold"].get<double>();
            pp.nms_threshhold = vobj["nms_threshhold"].get<double>();
            auto &anchors_list = vobj["anchors"].get<picojson::array>();//数组
            for(auto &anchor:anchors_list)
            {
                pp.anchors.push_back(anchor.get<double>());
            }
            auto &class_names = vobj["class_names"].get<picojson::array>();
            for (auto &name : class_names) {
                pp.class_names.push_back(name.get<std::string>());
            }
        }
        return pp;
    } catch (std::exception& e) {
        fprintf(stderr, "malformed config file: %s", e.what());
        exit(1);
    }
}

写入

    std::ifstream list_fs(images_file);
    if (!list_fs.is_open()) {
        printf("open %s failed\n", images_file.c_str());
        assert(0);
    }
    std::string line;
    picojson::value json;
    json.set<picojson::object>(picojson::object());
    while(std::getline(list_fs,line))
    {
        std::vector<uint8_t> image(input_size[0] * input_size[1] * 3, 0);
        cv::Mat mat = cv::imread(line);
        if (mat.empty())
        {
            fprintf(stderr, "Read image failed:%s.\n",line.c_str());
            // return -1;
            continue;
        }

        std::string::size_type iPos = line.find_last_of('/') + 1;
        std::string img_filename = line.substr(iPos, line.length() - iPos);//不带路径文件名
        std::string filename = img_filename.substr(0, img_filename.rfind("."));//不带后缀文件名
        // std::string suffix_str = img_filename.substr(img_filename.find_last_of('.') + 1);//后缀名
        fprintf(stdout,"img_filename:%s   finename: %s\n",img_filename.c_str(),filename.c_str());
        
        std::vector<detection::Object> objects;
        // 5. run the processing
		//省略板端处理
		
        json.get<picojson::object>()[img_filename].set<picojson::object>(picojson::object());

        for(size_t i=0;i<objects.size();i++)
        {
            const detection::Object& obj = objects[i];
            json.get<picojson::object>()[img_filename].get<picojson::object>()[std::to_string(i+1)].set<picojson::array>(picojson::array());
            json.get<picojson::object>()[img_filename].get<picojson::object>()[std::to_string(i+1)].get<picojson::array>().push_back(picojson::value(double(obj.label)));
            json.get<picojson::object>()[img_filename].get<picojson::object>()[std::to_string(i+1)].get<picojson::array>().push_back(picojson::value(double(obj.prob*100)));
            json.get<picojson::object>()[img_filename].get<picojson::object>()[std::to_string(i+1)].get<picojson::array>().push_back(picojson::value(double(obj.rect.x)));
            json.get<picojson::object>()[img_filename].get<picojson::object>()[std::to_string(i+1)].get<picojson::array>().push_back(picojson::value(double(obj.rect.y)));
            json.get<picojson::object>()[img_filename].get<picojson::object>()[std::to_string(i+1)].get<picojson::array>().push_back(picojson::value(double(obj.rect.x + obj.rect.width)));
            json.get<picojson::object>()[img_filename].get<picojson::object>()[std::to_string(i+1)].get<picojson::array>().push_back(picojson::value(double(obj.rect.y + obj.rect.height)));
        }
        
    }
    std::ofstream os;
    os.open("./result.txt");
    std::string json_txt = json.serialize(true);//true--美化json
    os<<json_txt;
    os.close();

生成的json

{
  "20210415_104301_ch3.jpg": {
    "1": [
      0,
      87.952301025390625,
      40.646713256835938,
      132.51205444335938,
      554.447265625,
      349.3531494140625
    ],
    "2": [
      0,
      83.141937255859375,
      1373.258544921875,
      620.5106201171875,
      1695.57373046875,
      833.6197509765625
    ],
    "3": [
      0,
      37.940631866455078,
      1865.757080078125,
      778.3056640625,
      1919,
      1018.0775146484375
    ]
  }
  }

参考:
https://www.mianshigee.com/project/picojson
https://blog.csdn.net/zhangpeng_linux/article/details/85857752

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值