private bool UndistortChessboardImage(Texture2D texture, CalculatedCameraIntrinsics intrinsics) { if (texture == null || texture.format != TextureFormat.RGB24) { return(false); } int imageWidth = texture.width; int imageHeight = texture.height; var unityPixels = texture.GetRawTextureData <byte>(); var pixels = unityPixels.ToArray(); if (!CalibrationAPI.Instance.UndistortChessboardImage( pixels, imageWidth, imageHeight, intrinsics)) { return(false); } for (int i = 0; i < unityPixels.Length; i++) { unityPixels[i] = pixels[i]; } texture.Apply(); return(true); }
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."); } }
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); } } }
public static CalculatedCameraIntrinsics LoadCameraIntrinsics(string path) { if (File.Exists(path)) { var fileData = File.ReadAllBytes(path); if (CalculatedCameraIntrinsics.TryDeserialize(fileData, out var intrinsics)) { return(intrinsics); } } Debug.LogError($"Failed to load camera intrinsics file {path}"); return(null); }
public static bool TryDeserialize(byte[] payload, out CalculatedCameraIntrinsics intrinsics) { intrinsics = null; try { var str = Encoding.UTF8.GetString(payload); intrinsics = JsonUtility.FromJson <CalculatedCameraIntrinsics>(str); return(true); } catch (Exception e) { Debug.LogWarning($"Exception thrown deserializing camera intrinsics: {e.ToString()}"); return(false); } }
public static string SaveCameraIntrinsics(CalculatedCameraIntrinsics intrinsics) { string path = Path.Combine(GetDocumentsFolderPath(), RootDirectoryName, $"CameraIntrinsics.json"); int i = 0; while (File.Exists(path)) { path = Path.Combine(GetDocumentsFolderPath(), RootDirectoryName, $"CameraIntrinsics_{i}.json"); i++; } var payload = intrinsics.Serialize(); File.WriteAllBytes(path, payload); return(path); }
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}"); } }
/// <summary> /// Calculates camera intrinsics using all provided chessboard images /// </summary> /// <param name="chessSquareSize">Size of a chessboard square in meters</param> /// <returns>Returns the calculated camera intriniscs, null if the camera intrinsics could not be calculated</returns> public CalculatedCameraIntrinsics CalculateChessboardIntrinsics(float chessSquareSize) { float[] output = new float[sizeIntrinsics]; if (ProcessChessboardIntrinsicsNative(chessSquareSize, output, sizeIntrinsics)) { var intrinsics = new CalculatedCameraIntrinsics( output[11], new Vector2(output[0], output[1]), // Focal length (uint)output[9], // Image width (uint)output[10], // Image height new Vector2(output[2], output[3]), // Principal point new Vector3(output[4], output[5], output[6]), // Radial distortion new Vector2(output[7], output[8]), // Tangential distortion Matrix4x4.identity); // Undistorted projection matrix, Note: not currently calculated return(intrinsics); } return(null); }
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); } } }
public CalibrationData(CalculatedCameraIntrinsics intrinsics, CalculatedCameraExtrinsics extrinsics) { cameraIntrinsics = intrinsics; cameraExtrinsics = extrinsics; }
public CalculatedCameraCalibration(CalculatedCameraIntrinsics intrinsics, CalculatedCameraExtrinsics extrinsics) { this.intrinsics = intrinsics; this.extrinsics = extrinsics; }