private void Start()
        {
            CalibrationDataHelper.Initialize();
            var chessboardImageFileNames = CalibrationDataHelper.GetChessboardImageFileNames();

            foreach (var fileName in chessboardImageFileNames)
            {
                var texture = CalibrationDataHelper.LoadChessboardImage(fileName);
                if (texture == null ||
                    !ProcessChessboardImage(texture))
                {
                    Debug.LogWarning($"Failed to process/locate chessboard image: {fileName}");
                }
                else
                {
                    CalibrationDataHelper.SaveChessboardDetectedImage(texture, fileName);
                }
            }

            if (chessboardHeatmap)
            {
                CalibrationDataHelper.SaveImage(chessboardHeatmap, "ChessboardHeatmap");
            }

            if (chessboardCorners)
            {
                CalibrationDataHelper.SaveImage(chessboardCorners, "ChessboardCorners");
            }
        }
        public void CalculateCameraIntrinsics()
        {
            if (processedImageCount > 0)
            {
                Debug.Log("Starting Camera Intrinsics calculation.");
                intrinsics = CalibrationAPI.Instance.CalculateChessboardIntrinsics(chessSquareSize);
                Debug.Log($"Chessboard intrinsics reprojection error: {intrinsics.ToString()}");
                intrinsicsFileName = CalibrationDataHelper.SaveCameraIntrinsics(intrinsics);
                Debug.Log($"Camera Intrinsics saved to file: {intrinsicsFileName}");

                // Undistort obtained images to understand quality of calculated camera intrinsics.
                var chessboardImageFileNames = CalibrationDataHelper.GetChessboardImageFileNames();
                foreach (var fileName in chessboardImageFileNames)
                {
                    var texture = CalibrationDataHelper.LoadChessboardImage(fileName);
                    if (texture == null ||
                        !UndistortChessboardImage(texture, intrinsics))
                    {
                        Debug.LogWarning($"Failed to locate/undistort chessboard image: {fileName}");
                    }
                    else
                    {
                        CalibrationDataHelper.SaveChessboardUndistortedImage(texture, fileName);
                    }
                }
            }
            else
            {
                Debug.LogWarning("No images have been processed, unable to calculate camera intrinsics.");
            }
        }
        public void TakePhoto()
        {
            if (CompositorWrapper.IsInitialized)
            {
                var dslrTexture = CompositorWrapper.Instance.GetVideoCameraTexture();
                var fileName    = CalibrationDataHelper.GetUniqueFileName();
                CalibrationDataHelper.SaveChessboardImage(dslrTexture, fileName);

                if (!ProcessChessboardImage(dslrTexture))
                {
                    Debug.LogWarning($"Failed to process/locate chessboard in dataset: {fileName}");
                }
                else
                {
                    processedImageCount++;
                    CalibrationDataHelper.SaveChessboardDetectedImage(dslrTexture, fileName);
                    CalibrationDataHelper.SaveImage(chessboardHeatmap, "ChessboardHeatmap");
                    CalibrationDataHelper.SaveImage(chessboardCorners, "ChessboardCorners");
                }
            }
            else
            {
                Debug.LogWarning("CompositorWrapper isn't initialized, failed to take photo.");
            }
        }
        private void Start()
        {
            CalibrationDataHelper.Initialize();
            dslrIntrinsics = CalibrationDataHelper.LoadCameraIntrinsics(cameraIntrinsicsPath);
            if (dslrIntrinsics == null)
            {
                throw new Exception("Failed to load the camera intrinsics file.");
            }
            else
            {
                Debug.Log($"Successfully loaded the provided camera intrinsics file: {dslrIntrinsics}");
            }

            networkingService = NetworkingService as INetworkingService;
            if (networkingService != null)
            {
                networkingService.DataReceived += OnDataReceived;
            }

            matchMakingService = MatchMakingService as IMatchMakingService;
            if (matchMakingService != null)
            {
                matchMakingService.Connect();
            }

            if (headsetCalibration != null)
            {
                headsetCalibration.Updated += OnHeadsetCalibrationUpdated;
            }

            var arucoDatasetFileNames = CalibrationDataHelper.GetArUcoDatasetFileNames();

            foreach (var fileName in arucoDatasetFileNames)
            {
                var dslrTexture = CalibrationDataHelper.LoadDSLRArUcoImage(fileName);
                var headsetData = CalibrationDataHelper.LoadHeadsetData(fileName);

                if (dslrTexture == null ||
                    headsetData == null)
                {
                    Debug.LogWarning($"Failed to locate dataset: {fileName}");
                }
                else if (!ProcessArUcoData(headsetData, dslrTexture))
                {
                    Debug.LogWarning($"Failed to process dataset: {fileName}");
                }
                else
                {
                    CalibrationDataHelper.SaveDSLRArUcoDetectedImage(dslrTexture, fileName);
                    CreateVisual(headsetData, fileName);
                }
            }
        }
        private void Update()
        {
            if (feedImage != null &&
                feedImage.texture == null)
            {
                feedImage.texture = CompositorWrapper.Instance.GetVideoCameraFeed();
            }

            if (cornersImage)
            {
                cornersImage.texture = chessboardCorners;
            }

            if (heatmapImage)
            {
                heatmapImage.texture = chessboardHeatmap;
            }

            if (Input.GetKeyDown(KeyCode.Space))
            {
                var dslrTexture = CompositorWrapper.Instance.GetVideoCameraTexture();
                var fileName    = CalibrationDataHelper.GetUniqueFileName();
                CalibrationDataHelper.SaveChessboardImage(dslrTexture, fileName);

                if (!ProcessChessboardImage(dslrTexture))
                {
                    Debug.LogWarning($"Failed to process/locate chessboard in dataset: {fileName}");
                }
                else
                {
                    CalibrationDataHelper.SaveChessboardDetectedImage(dslrTexture, fileName);
                    CalibrationDataHelper.SaveImage(chessboardHeatmap, "ChessboardHeatmap");
                    CalibrationDataHelper.SaveImage(chessboardCorners, "ChessboardCorners");
                }
            }

            if (Input.GetKeyDown(KeyCode.Return))
            {
                Debug.Log("Starting Camera Intrinsics calculation.");
                intrinsics = CalibrationAPI.Instance.CalculateChessboardIntrinsics(chessSquareSize);
                Debug.Log($"Chessboard intrinsics reprojection error: {intrinsics.ToString()}");
                var file = CalibrationDataHelper.SaveCameraIntrinsics(intrinsics);
                Debug.Log($"Camera Intrinsics saved to file: {file}");
            }
        }
        public CalibrationData(string cameraIntrinsicsPath, string cameraExtrinsicsPath)
        {
            if (File.Exists(cameraIntrinsicsPath) &&
                File.Exists(cameraExtrinsicsPath))
            {
                cameraIntrinsics = CalibrationDataHelper.LoadCameraIntrinsics(cameraIntrinsicsPath);
                cameraExtrinsics = CalibrationDataHelper.LoadCameraExtrinsics(cameraExtrinsicsPath);

                if (cameraIntrinsics == null ||
                    cameraExtrinsics == null)
                {
                    Debug.LogError($"Failed to load cameara intrinsics/extrinscs: {cameraIntrinsicsPath}, {cameraExtrinsicsPath}");
                }
            }
            else
            {
                Debug.LogError($"Invalid paths provided for camera intrinsics/extrinsics: {cameraIntrinsicsPath}, {cameraExtrinsicsPath}");
            }
        }
        private void Update()
        {
            if (feedImage != null &&
                feedImage.texture == null)
            {
                feedImage.texture = CompositorWrapper.Instance.GetVideoCameraFeed();
            }

            if (Input.GetKeyDown(KeyCode.Space))
            {
                RequestHeadsetData();
            }

            if (headsetData != null)
            {
                lastDetectedMarkersCount = headsetData.markers.Count;
                if (headsetData.markers.Count < MinimumNumberOfDetectedMarkers)
                {
                    Debug.Log("Data set did not contain enough markers to use.");
                }
                else
                {
                    var dslrTexture = CompositorWrapper.Instance.GetVideoCameraTexture();
                    var fileName    = CalibrationDataHelper.GetUniqueFileName();
                    CalibrationDataHelper.SaveDSLRArUcoImage(dslrTexture, fileName);
                    CalibrationDataHelper.SaveHeadsetData(headsetData, fileName);

                    if (ProcessArUcoData(headsetData, dslrTexture))
                    {
                        processedDatasetCount++;
                        CalibrationDataHelper.SaveDSLRArUcoDetectedImage(dslrTexture, fileName);
                        CreateVisual(headsetData, fileName);
                    }
                }

                headsetData = null;
            }

            if (Input.GetKeyDown(KeyCode.Return))
            {
                CalculateExtrinsics();
            }
        }
        private void Start()
        {
            holographicCameraObserver.RegisterCommandHandler(HeadsetCalibration.CalibrationDataReceivedCommandHeader, OnCalibrationDataReceived);
            holographicCameraObserver.RegisterCommandHandler(HeadsetCalibration.UploadCalibrationResultCommandHeader, OnCalibrationResultReceived);
            CalibrationAPI.Instance.Reset();
            CalibrationDataHelper.Initialize();
            dslrIntrinsics = CalibrationDataHelper.LoadCameraIntrinsics(cameraIntrinsicsPath);
            if (dslrIntrinsics == null)
            {
                throw new Exception("Failed to load the camera intrinsics file.");
            }
            else
            {
                Debug.Log($"Successfully loaded the provided camera intrinsics file: {dslrIntrinsics}");
            }

            var arucoDatasetFileNames = CalibrationDataHelper.GetArUcoDatasetFileNames();

            foreach (var fileName in arucoDatasetFileNames)
            {
                var dslrTexture = CalibrationDataHelper.LoadDSLRArUcoImage(fileName);
                var headsetData = CalibrationDataHelper.LoadHeadsetData(fileName);

                if (dslrTexture == null ||
                    headsetData == null)
                {
                    Debug.LogWarning($"Failed to locate dataset: {fileName}");
                }
                else if (!ProcessArUcoData(headsetData, dslrTexture))
                {
                    Debug.LogWarning($"Failed to process dataset: {fileName}");
                }
                else
                {
                    processedDatasetCount++;
                    CalibrationDataHelper.SaveDSLRArUcoDetectedImage(dslrTexture, fileName);
                    CreateVisual(headsetData, fileName);
                }
            }
        }
        /// <summary>
        /// Call to calculate camera extrinsics based on all obtained and usable datasets.
        /// </summary>
        public void CalculateExtrinsics()
        {
            if (processedDatasetCount > 0)
            {
                Debug.Log("Starting Individual Camera Extrinsics calculations.");
                cameraExtrinsics = CalibrationAPI.Instance.CalculateIndividualArUcoExtrinsics(dslrIntrinsics, parentVisuals.Count);
                if (cameraExtrinsics != null)
                {
                    CreateExtrinsicsVisual(cameraExtrinsics);
                }
                Debug.Log("Completed Individual Camera Extrinsics calculations.");

                Debug.Log("Starting the Global Camera Extrinsics calculation.");
                globalExtrinsics = CalibrationAPI.Instance.CalculateGlobalArUcoExtrinsics(dslrIntrinsics);
                if (globalExtrinsics != null)
                {
                    globalExtrinsicsFileName = CalibrationDataHelper.SaveCameraExtrinsics(globalExtrinsics);
                    Debug.Log($"Saved global extrinsics: {globalExtrinsicsFileName}");
                    Debug.Log($"Found global extrinsics: {globalExtrinsics}");
                    var        position = globalExtrinsics.ViewFromWorld.GetColumn(3);
                    var        rotation = Quaternion.LookRotation(globalExtrinsics.ViewFromWorld.GetColumn(2), globalExtrinsics.ViewFromWorld.GetColumn(1));
                    GameObject camera   = null;
                    cameraVisualHelper.CreateOrUpdateVisual(ref camera, position, rotation);
                    camera.name = "Global Extrinsics";
                    GameObject hololens = null;
                    cameraVisualHelper.CreateOrUpdateVisual(ref hololens, Vector3.zero, Quaternion.identity);
                    hololens.name = "Global HoloLens";

                    lastCalibration     = new CalculatedCameraCalibration(dslrIntrinsics, globalExtrinsics);
                    calibrationFileName = CalibrationDataHelper.SaveCameraCalibration(lastCalibration);
                }
            }
            else
            {
                Debug.LogWarning("No usable marker datasets have been processed, unable to calculate camera extrinsics.");
            }
        }
        private void Update()
        {
            if (feedImage != null &&
                feedImage.texture == null)
            {
                feedImage.texture = CompositorWrapper.Instance.GetVideoCameraFeed();
            }

            if (Input.GetKeyDown(KeyCode.Space))
            {
                if (networkingService != null &&
                    matchMakingService != null)
                {
                    var request = new HeadsetCalibrationDataRequest();
                    request.timestamp = Time.time;
                    var payload = request.Serialize();

                    if (networkingService.SendData(payload, NetworkPriority.Critical))
                    {
                        Debug.Log($"Sent headset calibration data request to HoloLens at {request.timestamp}");
                    }
                    else
                    {
                        Debug.LogWarning("Failed to send headset calibration data request to HoloLens");
                    }
                }

                if (headsetCalibration != null)
                {
                    Debug.Log("Requesting headset calibration data from VR Headset");
                    headsetCalibration.UpdateHeadsetCalibrationData();
                }
            }

            if (headsetData != null)
            {
                if (headsetData.markers.Count != expectedNumberOfMarkers)
                {
                    Debug.Log("Headset has not yet detected all of the markers on the calibration board, dropping payload from headset.");
                }
                else
                {
                    var dslrTexture = CompositorWrapper.Instance.GetVideoCameraTexture();
                    var fileName    = CalibrationDataHelper.GetUniqueFileName();
                    CalibrationDataHelper.SaveDSLRArUcoImage(dslrTexture, fileName);
                    CalibrationDataHelper.SaveHeadsetData(headsetData, fileName);

                    if (ProcessArUcoData(headsetData, dslrTexture))
                    {
                        CalibrationDataHelper.SaveDSLRArUcoDetectedImage(dslrTexture, fileName);
                        CreateVisual(headsetData, fileName);
                    }
                }

                headsetData = null;
            }

            if (Input.GetKeyDown(KeyCode.Return))
            {
                Debug.Log("Starting Individual Camera Extrinsics calculations.");
                cameraExtrinsics = CalibrationAPI.Instance.CalculateIndividualArUcoExtrinsics(dslrIntrinsics, parentVisuals.Count);
                if (cameraExtrinsics != null)
                {
                    foreach (var extrinsic in cameraExtrinsics)
                    {
                        Debug.Log($"Calculated extrinsics: {extrinsic}");
                    }
                    CreateExtrinsicsVisual(cameraExtrinsics);
                }

                Debug.Log("Starting the Global Camera Extrinsics calculation.");
                globalExtrinsics = CalibrationAPI.Instance.CalculateGlobalArUcoExtrinsics(dslrIntrinsics);
                if (globalExtrinsics != null)
                {
                    var fileName = CalibrationDataHelper.SaveCameraExtrinsics(globalExtrinsics);
                    Debug.Log($"Saved global extrinsics: {fileName}");
                    Debug.Log($"Found global extrinsics: {globalExtrinsics}");
                    var        position = globalExtrinsics.ViewFromWorld.GetColumn(3);
                    var        rotation = Quaternion.LookRotation(globalExtrinsics.ViewFromWorld.GetColumn(2), globalExtrinsics.ViewFromWorld.GetColumn(1));
                    GameObject camera   = null;
                    cameraVisualHelper.CreateOrUpdateVisual(ref camera, position, rotation);
                    camera.name = "Global Extrinsics";
                    GameObject hololens = null;
                    cameraVisualHelper.CreateOrUpdateVisual(ref hololens, Vector3.zero, Quaternion.identity);
                    hololens.name = "Global HoloLens";
                }
            }
        }