Skip to main content

Camera Calibration and Capture Bounds in C# (AR51.Net)

Run a camera calibration from your app, follow its progress, read the result — and read or set the tracked area (capture bounds).

The calibration itself

Starting a calibration from code doesn't change how it's done: someone still walks the lit calibration sphere through the capture area. See Camera calibration for good technique.

Run a calibration​

Calibration affects every app using the system

Tracking keeps running on the current calibration while a calibration runs. When it succeeds, it replaces every camera's calibration for every app connected to the AR 51 system; if it fails or is cancelled, the current calibration stays.

A calibration ends by itself once it has collected enough data. Subscribe to the events, then start it:

ar51.Calibration.CalibrationProgressChanged += (_, e) =>
Console.WriteLine($"{e.Status.Progress:P0}, error {e.Status.ReprojectionErrorPixels:F2} px {e.Status.Message}");
ar51.Calibration.CalibrationEnded += (_, e) =>
Console.WriteLine($"calibration {e.Result.Outcome}, error {e.Result.ReprojectionErrorPixels:F2} px");

await ar51.Calibration.StartCalibrationAsync();
  • Progress runs from 0 to 1. Reprojection error is in pixels — lower is better.
  • To finish now, call StopCalibrationAsync. It stops the running calibration — whoever started it, including one an operator started in Mocap Studio — and returns the result. Stopped before it has enough data, it ends as Cancelled and the cameras keep their previous values.
  • Starting one while another is running throws AR51Exception with Rejected.
Your app keeps the calibration alive

If your client is stopped or disposed — for example the app shuts down — before the calibration ends, the calibration is cancelled.

The result​

OutcomeMeaning
SucceededThe calibration succeeded; GetCamerasAsync returns the new values
FailedThe calibration failed; the cameras keep their previous values
CancelledStopped before it had enough data; the cameras keep their previous values
UnknownThe calibration was started by another app, or none was running

The events report every calibration, whoever started it (your app, Mocap Studio or another client). The outcome is known only for a calibration your client started.

Capture bounds​

The tracked area — the capture-area bounding box — is a box in the AR 51 world (meters): people outside it are not tracked.

CaptureBounds bounds = await ar51.Calibration.GetCaptureBoundsAsync();
Console.WriteLine($"center {bounds.Center} m, size {bounds.Size} m");
A wrong area makes people disappear

SetCaptureBoundsAsync applies immediately, and anyone outside the new box stops being tracked. Double-check the values first.

await ar51.Calibration.SetCaptureBoundsAsync(bounds with { Size = new Vector3(6, 2.5f, 6) });

CaptureBounds also gives you Min, Max and Contains(point).

Complete sample​

Run a calibration and follow its progress. It ends by itself once it has enough data; Ctrl+C stops it now (before it has enough data, that ends as Cancelled).

Program.cs
// Run a camera calibration and follow its progress. It ends by itself once it has enough data; Ctrl+C finishes it now.
using AR51.Net;

await using IAR51Client ar51 = AR51Client.Create();
var ended = new TaskCompletionSource<CalibrationResult>(TaskCreationOptions.RunContinuationsAsynchronously);

ar51.Calibration.CalibrationStarted += (_, e) => Console.WriteLine("Calibration started. Move the lit calibration sphere through the whole area.");
ar51.Calibration.CalibrationProgressChanged += (_, e) =>
Console.WriteLine($"{e.Status.Progress:P0}, error {e.Status.ReprojectionErrorPixels:F2} px {e.Status.Message}");
ar51.Calibration.CalibrationEnded += (_, e) => ended.TrySetResult(e.Result);

await ar51.StartAsync();
await ar51.Calibration.StartCalibrationAsync();

Console.CancelKeyPress += async (_, e) =>
{
e.Cancel = true;
CalibrationResult result = await ar51.Calibration.StopCalibrationAsync(); // "finish now"
ended.TrySetResult(result);
};

CalibrationResult final = await ended.Task;
Console.WriteLine($"Calibration ended: {final.Outcome}, error {final.ReprojectionErrorPixels:F2} px");
if (final.Outcome == CalibrationOutcome.Succeeded)
Console.WriteLine("The cameras' new calibration values are in ar51.Cameras.GetCamerasAsync().");

View this sample on Bitbucket — clone the samples repository to run it.

Reference​

ICalibrationClient · CalibrationStatus · CalibrationResult · CaptureBounds

Was this page helpful?