본문 바로가기
OpenCV

OpenCV ] 데이터 파일 입출력

by eteo 2022. 8. 18.

 

OpenCV에서는 영상 데이터가 아니라 int, float, double 등 일반적인 자료형과 Mat 클래스 객체 등을 XML, YAML, JSON 파일 형식으로 저장하는 기능을 제공하는데 FileStorage 클래스 사용

 

 

 

데이터 파일 저장하기

 

void writeData() {

	String name = "Jane";
	int age = 10;
	Point pt1(100, 200);
	vector<int> Scores = { 80,90,50 };
	Mat mat1 = (Mat_<float>(2, 2) << 1.0f, 1.5f, 2.0f, 3.2f);

	// filename의 확장자에 따라 맞는 형식으로 쓰여짐
	String filename = "mydata.json";
	//String filename = "mydata.xml";
	//String filename = "mydata.yml";

	// FileStorage 클래스의 open() 함수 또는 생성자를 사용하여 파일 오픈
	FileStorage fs(filename, FileStorage::WRITE);

	if (!fs.isOpened()) {
		cerr << "File open failed!" << endl;
		return;
	}

	// 파일에 데이터를 쓸 때 << 연산자 재정의 함수 사용
    // FileStorage 클래스를 사용시 데이터의 구분을 위한 문자열 형식의 데이터 이름을 먼저 저장하고
    // 그 후 실제 저장할 데이터를 저장함
	fs << "name" << name;
	fs << "age" << age;
	fs << "point" << pt1;
	fs << "scores" << Scores;
	fs << "data" << mat1;

	// 사용하던 파일을 닫고 메모리 버퍼 해제
	fs.release();
}

 

 

참고. 파일의 오픈 모드

FileStorage::READ 읽기 모드
FileStorage::WRITE 쓰기 모드(새로 생성)
FileStorage::APPEND 추가로 쓰기모드
FileStorage::MEMORY 논리합 | 연산자 사용, 파일 입출력 대신 메모리버퍼를 통한 입출력 수행

 

 

.json

 

 

.xml

 

.yml

 

 

 

 

 

 

 

데이터 파일 불러오기

 

void readData() {

	String name;
	int age;
	Point pt1;
	vector<int> scores;
	Mat mat1;

	String filename = "mydata.json";
	//String filename = "mydata.xml";
	//String filename = "mydata.yml";

	// 읽기 모드로 파일 오픈
	FileStorage fs(filename, FileStorage::READ);

	if (!fs.isOpened()) {
		cerr << "File open failed!" << endl;
		return;
	}
    
    // FileStorage 객체는 json/xml/yml 파일을 읽기모드로 열면 파일 전체를 분석하여 계층구조를 갖는 FileNode 집합을 구성함
    // FileNode 객체에 접근하는 것은 [] 연산자 재정의 함수 사용
    // FileNode 클래스에서 데이터를 읽을 때 >> 연산자 재정의 함수 사용
    /*
    FileNode fn = fs["name"];
    fn >> name;
    라고 해도 되지만 굳이 FileNode 변수를 안만들고 아래처럼 사용하는게 일반적임
    */
	fs["name"] >> name;
	fs["age"] >> age;
	fs["point"] >> pt1;
	fs["scores"] >> scores;
	fs["data"] >> mat1;

	fs.release();

	cout << "name:" << name << endl;
	cout << "age: " << age << endl;
	cout << "point: " << pt1 << endl;
    // scores는 vector<int> 형식 변수이고 Mat(scores)는 1열짜리 행렬로 생성되는데
    // Mat::t()함수를 호출해서 전치행렬을 구하면 1행짜리로 변환할 수 있음
	cout << "scores: " << Mat(scores).t() << endl;
	cout << "data:\n" << mat1 << endl;

}