前言
通常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