librealsense icon indicating copy to clipboard operation
librealsense copied to clipboard

rs2_depth_frame_get_distance doesn't work for software_device sensor

Open TimGameDev opened this issue 2 years ago • 14 comments

Hello,

I'm facing the same issue https://github.com/IntelRealSense/librealsense/issues/2844 in the latest version of SDK. I'm using .NET wrapper. In spite of the issue colorizer works fine.

I've tried to implement my own get_distance method like this

  private static unsafe float GetDistanceFromZ16(byte* dataPointer, int y, int x, float scale)
  {
        var index = (y * Width) + x;

        var b1 = *(dataPointer + index);
        var b2 = *(dataPointer + index + 1);
        var pixel = BitConverter.ToUInt16(new[] { b1, b2 });
        return pixel * scale;
  }

but the result doesn't seem correct. It might be a mistake somewhere.

Would be nice to have sdk api working for .NET and have some advice how to get distance from Z16 directly for performance reasons.

thank you, Tim

TimGameDev avatar Sep 07 '23 06:09 TimGameDev

Hi @TimGameDev Multiplying the pixel depth value by the depth unit scale value to obtain the real-world distance in meters is the correct approach.

You could try hard-coding the scale into the script instead of retrieving it in real-time from the camera if you are not doing so already. The scale value does not change unless deliberately changed by the user. The scale values for different RealSense camera models are listed below.

All 400 Series camera models except D405 0.001

D405 0.01

L515 0.000250


The RS2 instructions of the RealSense library can be accessed from the C# wrapper using Platform Invoke (P/Invoke).

https://github.com/IntelRealSense/librealsense/blob/master/wrappers/csharp/Documentation/pinvoke.md

MartyG-RealSense avatar Sep 07 '23 12:09 MartyG-RealSense

Hi @MartyG-RealSense I really appreciate such a quick response!

Let me split my message into two parts. First part is about an issue in SDK and it actually the main reason why I'm here :) The issue is GetDistance method for DepthFrame doesn't work for software device. The exact same issue was described here https://github.com/IntelRealSense/librealsense/issues/2844 long time ago, the only difference is that I'm using .NET.

Could you please take a look at this first, and then we will get back to all custom stuff :)

Thanks! Tim

TimGameDev avatar Sep 07 '23 21:09 TimGameDev

Hi @TimGameDev There should not be a need to use depth units in a get_distance() instruction. You would only need the depth scale if you were calculating real-world distance in meters with the alternative method of multiplying the pixel depth value (uint16_t) by the depth unit scale.

MartyG-RealSense avatar Sep 08 '23 12:09 MartyG-RealSense

I'm not sure I understand you unfortunately. Software Device should emulate behaviour of real device. Right? So it's kind of expected to have GetDistance Api working, because it's the most important one. The another thing is that this bug was definitely fixed before, please take a look at the issue I linked above. My guess is that it was fixed for specific language or it's just came back.

Thanks, Tim

On Fri, 8 Sept 2023, 10:19 pm MartyG-RealSense, @.***> wrote:

Hi @TimGameDev https://github.com/TimGameDev There should not be a need to use depth units in a get_distance() instruction. You would only need the depth scale if you were calculating real-world distance in meters with the alternative method of multiplying the pixel depth value (uinit16_t) by the depth unit scale.

— Reply to this email directly, view it on GitHub https://github.com/IntelRealSense/librealsense/issues/12170#issuecomment-1711581697, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD3YSSR4IUK726LRAV2K2FTXZMEOJANCNFSM6AAAAAA4OLXTFU . You are receiving this because you were mentioned.Message ID: @.***>

TimGameDev avatar Sep 08 '23 14:09 TimGameDev

If you have a problem with the get_distance method in https://github.com/IntelRealSense/librealsense/issues/2844 when using it with software-device then have you tested whether the other approach that was suggested in that case works with software-device?

aligner.process(fset);
auto depth_frame = aligned_frame.get_depth_frame();

MartyG-RealSense avatar Sep 08 '23 15:09 MartyG-RealSense

I get 0 all the time by calling GetDistance for DepthFrame object produced by Software Device (exactly as in the old issue). There's no difference between using aligner or not for me.

On Sat, 9 Sept 2023, 1:58 am MartyG-RealSense, @.***> wrote:

If you have a problem with the get_distance method in #2844 https://github.com/IntelRealSense/librealsense/issues/2844 when using it with software-device then have you tested whether the other approach that was suggested in that case works with software-device?

aligner.process(fset); auto depth_frame = aligned_frame.get_depth_frame();

— Reply to this email directly, view it on GitHub https://github.com/IntelRealSense/librealsense/issues/12170#issuecomment-1711894718, or unsubscribe https://github.com/notifications/unsubscribe-auth/AD3YSSWYS3Y4VN2DMWUPRR3XZM6A3ANCNFSM6AAAAAA4OLXTFU . You are receiving this because you were mentioned.Message ID: @.***>

TimGameDev avatar Sep 08 '23 16:09 TimGameDev

Would it be possible to post your full software device script in a comment so that I can highlight it to my Intel RealSense colleagues to identify whether there is a re-occuring bug in get_distance(), please?

MartyG-RealSense avatar Sep 09 '23 08:09 MartyG-RealSense

Sure! It's basically the code from your guides for software device but the simplest way to reproduce the issue for .NET would be:

            var sd = new Intel.RealSense.SoftwareDevice();
            var depthSensor = sd.AddSensor("Depth");
            depthSensor.AddReadOnlyOption(Option.DepthUnits, DepthScale);
            var syncer = new Syncer();

            var depthProfile = depthSensor.AddVideoStream(new SoftwareVideoStream()
            {
                index = 0,
                uid = 0,
                bpp = BPP_D,
                width = Width,
                height = Height,
                format = Format.Z16,
                fps = 60,
                type = Stream.Depth,
                intrinsics = _depthIntrinsics,
            });
            depthSensor.Open(depthProfile);
            depthSensor.Start(syncer.Queue);
            depthSensor.AddVideoFrame(DEPTH_FRAME_BYTES, Width * BPP_D, BPP_D, 0, TimestampDomain.HardwareClock, 1, depthProfile);

            var frame = syncer.Queue.WaitForFrame<DepthFrame>();

frame will have DataSize 0 and GetDistance will return 0. But colorizer will work fine for this frame.

And yes doing it with Context and Pipeline and two sensors provides the same result.

TimGameDev avatar Sep 09 '23 09:09 TimGameDev

I have highlighted your C# script to my colleagues and described the problem to them. Thanks very much for your patience!

MartyG-RealSense avatar Sep 09 '23 10:09 MartyG-RealSense

Hi @TimGameDev My colleagues have asked which camera you are working with, as the C# sample code requires a depth camera to work.

MartyG-RealSense avatar Sep 12 '23 09:09 MartyG-RealSense

Hi @MartyG-RealSense, I thought I did mention that, my bad. Camera is D455.

TimGameDev avatar Sep 12 '23 09:09 TimGameDev

Thanks, I will feed that information back to my colleagues.

MartyG-RealSense avatar Sep 12 '23 11:09 MartyG-RealSense

Hi again @TimGameDev My colleagues were able to reproduce the GetDistance() issue using software device in C# and have begun work on a fix at https://github.com/IntelRealSense/librealsense/pull/12193

I have added an Enhancement label to this case to signify that it should be kept open until the fix has been implemented in the SDK. Thanks again for your report!

MartyG-RealSense avatar Sep 14 '23 16:09 MartyG-RealSense

Hi @MartyG-RealSense, thank you for the update. Glad to help.

TimGameDev avatar Sep 14 '23 21:09 TimGameDev