[opencv] XML, YAML 데이터 처리
OPENCV를 공부하면서 배워야 할 기본클래스들에 대한 커리큘럼의 최정점에 도착했다.
FileStorage를 이용한 XML과 YAML파일 읽고 쓰기.
그런데 XML은 알겠는데 YAML은 무엇…인가?
YAML is mush less verbose.
https://stackoverflow.com/questions/1308536/yaml-compared-to-xml
XML, HTML, YAML 전부 마크업 랭귀지이다.
특히 XML은 JSON과 계층적 데이터집합 시리즈의 양대산맥을 이루고 있는 마크업 랭귀지다.
YAML은 XML보다 더 간단하게(적은 문법으로(less verbose)) 계층적인 데이터셋을 만들 수 있다.
#include <opencv2\opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(void) { FileStorage fs("test.xml", FileStorage::WRITE); time_t date; time(&date); fs << "Date" << asctime(localtime(&date)); fs << "string" << "TEST"; // write as string fs << "integer" << 180; // write as int(eventually write string) // [ ] : 시퀀스 컬렉션 fs << "collection_seq" << "["; fs << "sequence1" << "sequence2"; fs << "sequence3" << "]"; // end of sequence collection // { } : 매핑 컬렉션 fs << "collection_map" << "{"; fs << "mapping1" << 100; fs << "mapping2" << "someString2"; fs << "}"; // end of maaping collection return 0; }
[ ](Sequence Collection)과 { }(Mapping Collection)만 이해하고 있다면 어려울 게 전혀없는 직관적인 핸들링이다.
또한 아래처럼 Vector를 통째로 마크업 문서에 저장하는 것도 가능하다.
int arr[] = {1,2,3,4,5,6,7,8,9}; vector<int> V1(arr, arr+sizeof(arr)/sizeof(arr[0])); fs << "V1" << V1;
(파일 내부의 결과는 <V1> 1 2 3 4 5 6 7 8 9 </V1> 인 시퀀스 컬렉션으로 기록된다)
Mat같은 커다란 덩치의 객체를 output해도 문제없다.
심지어 편리하게 알아서 계층적구조를 만들어준다(rows, cols, data등…)
읽는 것 역시 크게 어려울 것 없이
FileStorage fs("test.xml", FileStorage::READ);
로 읽기 모드로 마크업문서를 열면 된다. 접근은 Python에서 dict객체 접근하듯
fs[“section”] 로 접근하면 밸류가 튀어나온다.
String값 일때는 String이 튀어나오고 int값 일때는 int가 튀어나오고 한다.
단, 위와 같이 단일 값이 아닌 데이터 밑에 계층적구조를 가지고 있다면
FileNode node = fs["SomeNode"];
처럼 불러와야 한다.
node.isString(); node.isInt();
와 같이 자료형에 대한 검증도 지원하므로 FileNode를 사용하는것이 런타임에러를 줄이기 위한 안전한 방법이 되겠다.
135개의 댓글