/// <summary> /// Serialize calibration points map to a file on the device. /// </summary> /// <param name="calibrationPointsMap">The calibration points map to serialize.</param> /// <param name="writeFile">The device file to serialize to.</param> /// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns> internal static async Task <bool> SerializeAsync(this CalibrationPointsMap calibrationPointsMap, StorageFile writeFile) { using var stream = await writeFile.OpenStreamForWriteAsync(); using var writer = new BinaryWriter(stream); writer.Write(calibrationPointsMap.Width); writer.Write(calibrationPointsMap.Height); writer.Write(calibrationPointsMap.CameraUnitPlanePoints.Length); foreach (var value in calibrationPointsMap.CameraUnitPlanePoints) { writer.Write(value); } return(true); }
/// <summary> /// Computes camera intrinsics from a map of calibration points. /// </summary> /// <param name="calibrationPointsMap">The map of calibration points to compute camera intrinsics from.</param> /// <returns>The computed <see cref="CameraIntrinsics"/>.</returns> internal static CameraIntrinsics ComputeCameraIntrinsics(this CalibrationPointsMap calibrationPointsMap) { var width = calibrationPointsMap.Width; var height = calibrationPointsMap.Height; // Convert unit plane points in the calibration map to a lookup table mapping image points to 3D points in camera space. List <Point3D> cameraPoints = new (); List <Point2D> imagePoints = new (); int ci = 0; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { var x = calibrationPointsMap.CameraUnitPlanePoints[ci++]; var y = calibrationPointsMap.CameraUnitPlanePoints[ci++]; if (!double.IsNaN(x) && !double.IsNaN(y)) { var norm = Math.Sqrt((x * x) + (y * y) + 1.0); imagePoints.Add(new Point2D(i + 0.5, j + 0.5)); cameraPoints.Add(new Point3D(x / norm, y / norm, 1.0 / norm)); } } } // Initialize a starting camera matrix var initialCameraMatrix = Matrix <double> .Build.Dense(3, 3); var initialDistortion = VectorDouble.Build.Dense(2); initialCameraMatrix[0, 0] = 250; // fx initialCameraMatrix[1, 1] = 250; // fy initialCameraMatrix[0, 2] = width / 2.0; // cx initialCameraMatrix[1, 2] = height / 2.0; // cy initialCameraMatrix[2, 2] = 1; CalibrationExtensions.CalibrateCameraIntrinsics( cameraPoints, imagePoints, initialCameraMatrix, initialDistortion, out var computedCameraMatrix, out var computedDistortionCoefficients, false); return(new CameraIntrinsics(width, height, computedCameraMatrix, computedDistortionCoefficients)); }