Unity Editor version : 2022.3.42f1 ML2 OS version : 1.8.0 Unity SDK version : 2.5.0 Host OS : MacOS
Hi, I am working on a project where I would like to use the 2D coordinates from my object detection model and convert them to world space using the depth camera. But I’m a bit confused on where to start, as the other posts here seem to be using a different API then is in the current documentation. Could you please point me in the right direction. Thank you!
I think the other link was in reference to how another device aligns the data from the two sensors, not that it is specific to the device. You are correct to use the Pixel Sensor API.
We do not provide SDK functionality to align or synchronize sensors, so this would need to be done using custom logic in your application. Note that the RGB camera and the Depth camera are not located at the same place on the Magic Leap Headset. So you will need to use the Intrinsic and Extrinsic data to align the RGB and Depth images.
Thank you! That helped me make a good start. However I’m getting stuck when getting the pose of the frame. I’m doing it as soon as the camera callback is triggered as suggested in the other post. But I’m getting the same MLCVCameraGetFramePose error and I’m really confused as to why. Here is my function:
If you are using OpenXR , you will need to make sure the Perception Snapshots is enabled in the OpenXR Magic Leap Support Feature in your project settings
You will need to make sure to get the pose of the camera within 500ms of the callback. This means that you need to maintain a high frame rate, otherwise the timestamp might become invalid.
You can also use the OpenXR Pixel Sensor logic to obtain the camera pose. This way you don’t have to convert between OpenXR and MLSDK poses. Note, that if you are using the MLCamera , you can just use the following example without additional configuration. Just call GetSensorPose in the callback.
Callback example
private MagicLeapPixelSensorFeature _pixelSensorFeature;
private PixelSensorId _sensorType;
private XROrigin _xrOrigin;
...
void RawVideoFrameAvailable(MLCamera.CameraOutput output, MLCamera.ResultExtras extras, MLCameraBase.Metadata metadataHandle)
{
if (output.Format == MLCamera.OutputFormat.RGBA_8888)
{
//Flips the frame vertically so it does not appear upside down.
MLCamera.FlipFrameVertically(ref output);
UpdateRGBTexture(ref _videoTextureRgb, output.Planes[0], _screenRendererRGB);
}
if(_pixelSensorFeature == null)
{
_pixelSensorFeature = OpenXRSettings.Instance.GetFeature<MagicLeapPixelSensorFeature>();
_sensorType = _pixelSensorFeature.GetSupportedSensors().Find(x=> x.SensorName == "Picture Center"); // Simplified for example
bool wasCreated = _pixelSensorFeature.CreatePixelSensor(_sensorType);
}
Pose sensorPose = _pixelSensorFeature.GetSensorPose(_sensorType);
// Updates the Sensor Pose to be relative to the XR Origin
if (_xrOrigin = FindAnyObjectByType<XROrigin>())
{
Vector3 worldPosition = _xrOrigin.CameraFloorOffsetObject.transform.TransformPoint(sensorPose.position);
Quaternion worldRotation = _xrOrigin.transform.rotation * sensorPose.rotation;
// Update the existing pose
sensorPose = new Pose(worldPosition, worldRotation);
}
Debug.Log("Sensor Position:" + sensorPose.position);
Debug.Log("Sensor Rotation:" + sensorPose.rotation);
}
Hi thank you for this. What does it mean that the sensor pose is relative to the XR origin?
I am using the MLDepthCamera like this, I’m assuming there’s no difference in what the PixelSensor and the MLDepthCamera return?:
public override void Update()
{
//Debug.Log("Depth camera update");
if (!permissionGranted || !MLDepthCamera.IsConnected) return;
var result = MLDepthCamera.GetLatestDepthData(0, out MLDepthCamera.Data data);
isFrameAvailable = result.IsOk;
if (isFrameAvailable)
{
lastData = data;
DepthCameraIntrinsics.fx = data.Intrinsics.FocalLength.x;
DepthCameraIntrinsics.fy = data.Intrinsics.FocalLength.y;
DepthCameraIntrinsics.cx = data.Intrinsics.PrincipalPoint.x;
DepthCameraIntrinsics.cy = data.Intrinsics.PrincipalPoint.y;
DepthCameraIntrinsics.width = data.Intrinsics.Width;
DepthCameraIntrinsics.height = data.Intrinsics.Height;
DepthCameraExtrinsics.position = data.Position;
DepthCameraExtrinsics.rotation = Matrix4x4.Rotate(data.Rotation);
DepthCameraExtrinsics.timestamp = data.FrameTimestamp;
}
}
Also do you have any advice on aligning the image from the CV Camera and depth camera as I am struggling to.
I was also wondering if you could explain how to access the depth information from the MLDepthCamera.FrameBuffer depthFrame. I’m currently converting it into an array to get the depth value at each pixel, but my depth values seem to be too high.
This is because the MLSDK returns a Pose in a diferent space which is the equivalent of OpenXR’s unbounded.
Regarding the Depth Camera API:
Please note, the MLSDK API (MLDepthCamera) has been deprecated in favor of the OpenXR Magic Leap Pixel Sensor API. This means that the API will not receive updates and is no longer supported. That said, here is an old post regarding the ML Depth Camera: