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; } } }