using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEngine;
using Seengene.XDKUnityPluginCloud;
public class CameraCalibrationLoader {
///
/// 眼类型
///
public enum EyeType {
///
/// 左眼
///
LeftEye = 0,
///
/// 右眼
///
RightEye = 1
}
private static string configXmlPath;
private const string k_DefaultConfigXmlPath = "/persist/qvr/device_calibration.xml";
public const string k_XmlDocumentName = "device_calibration.xml";
public const string k_XmlNodeName_Root = "DeviceConfiguration";
public const string k_XmlNodeName_LevelOne = "Camera";
public const string k_XmlNodeName_LevelTwo = "Calibration";
public const string k_XmlNodeAttributeName_EyeID = "id";
public const string k_XmlNodeAttributeName_FocalLength = "focal_length";
public const string k_XmlNodeAttributeName_PrincipalPoint = "principal_point";
public const string k_XmlNodeAttributeName_Resolution = "size";
public const string k_XmlNodeAttributeName_FishEye = "fish_eye";
public const string k_XmlNodeAttributeName_RadialDistortion8 = "radial_distortion_8";
public const string k_XmlNodeAttributeName_Model = "model";
public const string k_XmlNodeAttributeName_RadialDistortion = "radial_distortion";
private static void Init() {
#if UNITY_EDITOR
configXmlPath = Path.Combine(Application.streamingAssetsPath, k_XmlDocumentName);
#else
configXmlPath = k_DefaultConfigXmlPath;
#endif
}
public static CameraCalibration GetCameraCalibration(EyeType eyeType) {
Init();
if (!File.Exists(configXmlPath)) {
Debug.LogErrorFormat("读取相机内参失败,相机标定文件不存在: {0}", configXmlPath);
return null;
}
Vector2 focalLength = Vector2.zero;
Vector2 principalPoint = Vector3.zero;
Vector2Int resolution = Vector2Int.zero;
bool fishEye = false;
float[] radialDistortion8 = null;
string model = string.Empty;
float[] radialDistortion = null;
XmlDocument myXmlDoc = new XmlDocument();
string str = File.ReadAllText(configXmlPath);
myXmlDoc.LoadXml(str);
XmlNode rootNode = myXmlDoc.SelectSingleNode(k_XmlNodeName_Root);
XmlNodeList nodeList_L1 = rootNode.ChildNodes;
foreach (XmlNode node_L1 in nodeList_L1) {
if (node_L1.Name == k_XmlNodeName_LevelOne) {
// 标识位,是否是要查找的相机内参的眼睛
bool isTargetEye = false;
XmlAttributeCollection attributeCol_L1 = node_L1.Attributes;
foreach (XmlAttribute attri in attributeCol_L1) {
string name = attri.Name;
string value = attri.Value;
if (name == k_XmlNodeAttributeName_EyeID && value == ((int)eyeType).ToString()) {
isTargetEye = true;
break;
}
}
if (isTargetEye) {
if (node_L1.HasChildNodes) {
XmlNodeList nodeList_L2 = node_L1.ChildNodes;
foreach (XmlNode node_L2 in nodeList_L2) {
string name = node_L2.Name;
if (name == k_XmlNodeName_LevelTwo) {
XmlAttributeCollection attibuteCol_L2 = node_L2.Attributes;
foreach (XmlAttribute attri in attibuteCol_L2) {
if (attri.Name == k_XmlNodeAttributeName_Resolution) {
// 图片分辨率
try {
string value = attri.Value;
string[] arrValue = value.Split(" "[0]);
if (arrValue.Length >= 2) {
int width = int.Parse(arrValue[0]);
int height = int.Parse(arrValue[1]);
resolution = new Vector2Int(width, height);
} else {
Debug.LogErrorFormat("读取相机内参失败:{0}", "解析图片分辨率时出错");
break;
}
} catch (Exception e) {
Debug.LogErrorFormat("读取相机内参失败:{0}", e.Message);
break;
}
}
if (attri.Name == k_XmlNodeAttributeName_PrincipalPoint) {
// 主点
try {
string value = attri.Value;
string[] arrValue = value.Split(" "[0]);
if (arrValue.Length >= 2) {
float x = float.Parse(arrValue[0]);
float y = float.Parse(arrValue[1]);
principalPoint = new Vector2(x, y);
} else {
Debug.LogErrorFormat("读取相机内参失败:{0}", "解析图片主点参数时出错");
break;
}
} catch (Exception e) {
Debug.LogErrorFormat("读取相机内参失败:{0}", e.Message);
break;
}
}
if (attri.Name == k_XmlNodeAttributeName_FocalLength) {
// 焦距
try {
string value = attri.Value;
string[] arrValue = value.Split(" "[0]);
if (arrValue.Length >= 2) {
float x = float.Parse(arrValue[0]);
float y = float.Parse(arrValue[1]);
focalLength = new Vector2(x, y);
} else {
Debug.LogErrorFormat("读取相机内参失败:{0}", "解析图片焦距参数时出错");
break;
}
} catch (Exception e) {
Debug.LogErrorFormat("读取相机内参失败:{0}", e.Message);
break;
}
}
if (attri.Name == k_XmlNodeAttributeName_FishEye) {
// 是否是鱼眼图
try {
string value = attri.Value;
if (value == "true") {
fishEye = true;
} else {
fishEye = false;
}
} catch (Exception e) {
Debug.LogErrorFormat("读取相机内参失败:{0}", e.Message);
break;
}
}
if (attri.Name == k_XmlNodeAttributeName_RadialDistortion8) {
// 8位图片畸变参数
try {
string value = attri.Value;
//Debug.Log("radialDistortion8: " + value);
string[] arrValue = value.Split(" "[0]);
//Debug.Log("arrValue.Length: " + arrValue.Length);
//Debug.Log(XDKTools.OneDimensionArrayToString(arrValue));
if (arrValue.Length >= 8) {
float p0 = float.Parse(arrValue[0]);
float p1 = float.Parse(arrValue[1]);
float p2 = float.Parse(arrValue[2]);
float p3 = float.Parse(arrValue[3]);
float p4 = float.Parse(arrValue[4]);
float p5 = float.Parse(arrValue[5]);
float p6 = float.Parse(arrValue[6]);
float p7 = float.Parse(arrValue[7]);
radialDistortion8 = new float[8] { p0, p1, p2, p3, p4, p5, p6, p7 };
//Debug.Log("radialDistortion8: " + XDKTools.ArrayFloatToString(radialDistortion8));
} else {
Debug.LogErrorFormat("读取相机内参失败:{0}", "解析图片\"8位图片畸变参数\"时出错");
break;
}
} catch (Exception e) {
Debug.LogErrorFormat("读取相机内参失败:{0}", e.Message);
break;
}
}
if (attri.Name == k_XmlNodeAttributeName_Model) {
// 相机模型 model
try {
model = attri.Value;
//Debug.Log("model: " + model);
} catch (Exception e) {
Debug.LogErrorFormat("读取相机内参失败:{0}", e.Message);
break;
}
}
if (attri.Name == k_XmlNodeAttributeName_RadialDistortion) {
// 图片畸变参数
try {
string value = attri.Value;
//Debug.Log("radialDistortion: " + value);
string[] arrValue = value.Split(" "[0]);
//Debug.Log("arrValue.Length: " + arrValue.Length);
//Debug.Log(XDKTools.OneDimensionArrayToString(arrValue));
if (arrValue.Length >= 6) {
float p0 = float.Parse(arrValue[0]);
float p1 = float.Parse(arrValue[1]);
float p2 = float.Parse(arrValue[2]);
float p3 = float.Parse(arrValue[3]);
float p4 = float.Parse(arrValue[4]);
float p5 = float.Parse(arrValue[5]);
radialDistortion = new float[6] { p0, p1, p2, p3, p4, p5 };
} else {
Debug.LogErrorFormat("读取相机内参失败:{0}", "解析图片\"图片畸变参数\"时出错");
}
Debug.Log("radialDistortion: " + radialDistortion);
} catch (Exception e) {
Debug.LogErrorFormat("读取相机内参失败:{0}", e.Message);
break;
}
}
}
}
}
}
}
}
}
if (focalLength != Vector2.zero && principalPoint != Vector2.zero && resolution != Vector2.zero) {
CameraCalibration cameraIntrinsics = new CameraCalibration(focalLength, principalPoint, resolution, fishEye, radialDistortion8, model, radialDistortion);
return cameraIntrinsics;
} else {
return null;
}
}
}