本文主要使用实际例子分析opencv的XML读写:
在前文分析了Qt 对XML文件的读写,详细内容见链接:https://blog.csdn.net/weixin_38293453/article/details/104173228
添加相opencv xml关头文件:
#include <opencv2/opencv.hpp>
opencv对XML的写配置文件:
写是以数据流的形式进行写配置的,理解了这一点程序就很好理解了。
void CameraCalibration::saveCameraConfig(const char *path, std::vector<std::string> &cameraParam)
{
cv::FileStorage fs(path, cv::FileStorage::WRITE);
fs << "NumOfCorners_for_each_img" << "{:";
fs << "numOfCornersX" << cameraParam[0] << "numOfCornersY" << cameraParam[1];
fs<<"}";
fs << "BoardSquare" << "{:";
fs << "Height" << cameraParam[2] << "Width" << cameraParam[3];
fs<<"}";
fs << "calibrationPath" << "{:";
fs << "calibPath" << cameraParam[4] << "exCalibPath" << cameraParam[5];
fs<<"}";
if(cameraParam.size() == 10)
{
fs << "ProjectorImgCorners" << "{:";
fs << "numOfProjectorImgCornersX" << cameraParam[6] << "numOfProjectorImgCornersY" << cameraParam[7];
fs<<"}";
fs << "ProjectImgPath" << "{:";
fs << "Path" << cameraParam[8];
fs<<"}";
fs << "ProjectHomoDir" << "{:";
fs << "DirPath" << cameraParam[9];
fs<<"}";
}
fs.release();
}
opencv对XML的读配置文件:
读是以节点Node为单位进行读取的,理解了这一点程序就很好理解了。
void CameraCalibration::loadCameraConfig(const char *path,std::vector<std::string> &cameraParam)
{
cv::FileStorage fs(path, cv::FileStorage::READ);
if(!fs.isOpened())
{
std::cout << "Failed to open Calibration Data File. " << std::endl;
return;
}
cv::FileNode node = fs["NumOfCorners_for_each_img"];
node["numOfCornersX"] >> cameraParam[0];
node["numOfCornersY"] >> cameraParam[1];
node = fs["BoardSquare"];
node["Height"] >> cameraParam[2];
node["Width"] >> cameraParam[3];
node = fs["calibrationPath"];
node["calibPath"] >> cameraParam[4];
node["exCalibPath"] >> cameraParam[5];
if(cameraParam.size() == 10)
{
node = fs["ProjectorImgCorners"];
node["numOfProjectorImgCornersX"] >> cameraParam[6];
node["numOfProjectorImgCornersY"] >> cameraParam[7];
node = fs["ProjectImgPath"];
node["Path"] >> cameraParam[8];
node = fs["ProjectHomoDir"];
node["DirPath"] >> cameraParam[9];
}
fs.release();
}
下面介绍稍微复杂点的例子,节点带属性,对属性的理解可以参考QT XML。
写XML
void CameraCalibration::saveCalibData(const char *path)
{
cv::FileStorage fs(path, cv::FileStorage::WRITE);
fs << "Camera" << "{:";
fs<< "Calibrated" << camCalibrated << "Matrix" << camMatrix << "Distortion" << distortion<<"Translation"<<translationVector<<"Rotation"<<rotationMatrix;
fs<<"Height" << camImageSize.height<<"Width" << camImageSize.width<<"total_err" << total_err<<"err_of_extrImg" <<err_of_extrImg;
fs<<"}";
fs << "BoardSquare" << "{:";
fs << "Height" << squareSize.height << "Width" << squareSize.width;
fs<<"}";
fs << "NumOfCorners_for_each_img" << "{:";
fs << "numOfCornersX" << numOfCornersX << "numOfCornersY" << numOfCornersY;
fs<<"}";
fs << "ExtractedFeatures" << "{:";
fs << "CameraImages" << "{:";
int size = imgBoardCornersCam.size();
fs << "NumberOfImgs" << size;
for(int i=0; i<imgBoardCornersCam.size(); i++)
{
std::stringstream name;
name << "Image" << i+1;
fs<<name.str()<< "{:";
fs<<"BoardCorners"<<imgBoardCornersCam[i];
fs<<"ObjBoardCorners"<<objBoardCornersCam[i];
fs<<"}";
}
fs<<"}";
fs<<"}";
fs.release();
}
读XML
void CameraCalibration::loadCalibData(const char *path)
{
cv::FileStorage fs(path, cv::FileStorage::READ);
if(!fs.isOpened())
{
std::cout << "Failed to open Calibration Data File. " << std::endl;
return;
}
cv::FileNode node = fs["Camera"];
node["Calibrated"] >> camCalibrated;
node["Matrix"] >> camMatrix;
node["Distortion"]>> distortion;
node["Rotation"]>> rotationMatrix;
node["Translation"] >> translationVector;
node["Height"] >> camImageSize.height;
node["Width"] >> camImageSize.width;
node["total_err"] >> total_err;
node["err_of_extrImg"] >> err_of_extrImg;
node = fs["BoardSquare"];
node["Height"] >> squareSize.height;
node["Width"] >> squareSize.width;
node = fs["NumOfCorners_for_each_img"];
node["numOfCornersX"] >> numOfCornersX;
node["numOfCornersY"] >> numOfCornersY;
cv::FileNode features = fs["ExtractedFeatures"];
cv::FileNode images = features["CameraImages"];
int size = images["NumberOfImgs"];
for(int i=0; i<size; i++)
{
std::stringstream name;
name << "Image" << i+1;
cv::FileNode image = images[name.str()];
std::vector<cv::Point2f> in2;
std::vector<cv::Point3f> in3;
image["BoardCorners"]>>in2;
imgBoardCornersCam.push_back(in2);
image["ObjBoardCorners"]>>in3;
objBoardCornersCam.push_back(in3);
}
fs.release();
}
总结:Opencv XML对矩阵、数组的读写具有很大的优势,这是Qt XML所不具备的,因此在实际的应用中,根据具体需求来确定使用那一种XML。