以下是OpenCV(https://docs.opencv.org/3.4.0/d4/da4/group__core__xml.html)的示例(代码的一部分):
test.yml
%YAML:1.0
---
frameCount: 5
read.cpp
#include "opencv2/opencv.hpp"
#include <time.h>
using namespace cv;
using namespace std;
int main()
{
FileStorage fs("test.yml", FileStorage::READ);
int frameCount = (int) fs["frameCount"];
cout << frameCount << endl;
return 0;
}
给出代码,它可以正常工作并读取yaml文件。但是当我删除%YAML:1.0时,代码将抛出:
OpenCV Error: Unknown error code -49 (Input file is empty) in cvOpenFileStorage, file /home/pengfei/Documents/opencv-3.3.1/modules/core/src/persistence.cpp, line 4484
terminate called after throwing an instance of 'cv::Exception'
what(): /home/pengfei/Documents/opencv-3.3.1/modules/core/src/persistence.cpp:4484: error: (-49) Input file is empty in function cvOpenFileStorage
[1] 27146 abort (core dumped) ./Read
但是我检查了yaml.org。没有规则说明必须使用%YAML:1.0。 (http://yaml.org/start.html)
**我的问题是(根据@zindarod的回答更新):**
1。这是OpenCV的特定功能吗?
是的,这是OpenCV的特定要求。
const char* yaml_signature = "%YAML";
const char* json_signature = "{";
const char* xml_signature = "<?xml";
OpenCV检查文件签名,然后决定如何解释文件。
2。如何知道我应该使用的Yaml版本?
yaml版本并不重要。
但是最好使用1.0规范。 OpenCV可能无法解析其他新规范。
答案 0 :(得分:3)
在OpenCV-3.3.1中,函数cvOpenFileStorage
位于/modules/core/src/persistence.cpp
:
...
else
{
if( mem )
{
fs->strbuf = filename;
fs->strbufsize = fnamelen;
}
size_t buf_size = 1 << 20;
const char* yaml_signature = "%YAML";
const char* json_signature = "{";
const char* xml_signature = "<?xml";
char buf[16];
icvGets( fs, buf, sizeof(buf)-2 );
char* bufPtr = cv_skip_BOM(buf);
size_t bufOffset = bufPtr - buf;
if(strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0)
fs->fmt = CV_STORAGE_FORMAT_YAML;
else if(strncmp( bufPtr, json_signature, strlen(json_signature) ) == 0)
fs->fmt = CV_STORAGE_FORMAT_JSON;
else if(strncmp( bufPtr, xml_signature, strlen(xml_signature) ) == 0)
fs->fmt = CV_STORAGE_FORMAT_XML;
else if(fs->strbufsize == bufOffset)
CV_Error(CV_BADARG_ERR, "Input file is empty");
...
OpenCV检查文件签名(json,yaml和xml)。只要第一行中包含字符串“ %YAML ”,YAML的版本就无关紧要。