Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question I want AR Raycast distance values for every coordinate on the screen

Discussion in 'AR' started by chanmob, Jun 13, 2023.

  1. chanmob

    chanmob

    Joined:
    Mar 28, 2016
    Posts:
    11
    Code (CSharp):
    1.             float[,] ray_array = new float[Screen.width + 1, Screen.height + 1];
    2.  
    3.             for (int y = 0; y <= Screen.height; y++)
    4.             {
    5.                 for (int x = 0; x <= Screen.width; x++)
    6.                 {
    7.                     List<ARRaycastHit> hits = new List<ARRaycastHit>();
    8.  
    9.                     if (ray_manager.Raycast(new Vector2(x, y), hits, TrackableType.Depth))
    10.                     {
    11.                         ray_array[x, y] = hits[0].distance;
    12.                     }
    13.                 }
    14.             }
    I wrote a for loop in this way to get the values of all coordinates, but the for loop is too slow. Is there a way to improve the speed?
     
  2. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
  3. chanmob

    chanmob

    Joined:
    Mar 28, 2016
    Posts:
    11
  4. chanmob

    chanmob

    Joined:
    Mar 28, 2016
    Posts:
    11
  5. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    The page I posted links to a sample here.

    I've never played around with the depth image myself and so I can't really help you with the details.
     
  6. andyb-unity

    andyb-unity

    Unity Technologies

    Joined:
    Feb 10, 2022
    Posts:
    774
    Calculating the distance of every point via raycasting is very computationally intensive. @zulo3d has it right that you likely will achieve better results by sampling the depth map.
     
  7. chanmob

    chanmob

    Joined:
    Mar 28, 2016
    Posts:
    11
    upload_2023-6-16_13-59-52.png

    I took an XRCPUImage and took a test of the floor. In this case, the depth length of the camera center point should be about 0.36, and the depth length of the otherside should be higher than the center of the camera, but most of the depth is the same at 0.36. I think it comes out well when I debug with raycast, but if raycast is inefficient, is there any other solution?
     
  8. chanmob

    chanmob

    Joined:
    Mar 28, 2016
    Posts:
    11
    here is my code

    Code (CSharp):
    1.         public void SaveCpuImageData()
    2.         {
    3.             if (manager.descriptor.environmentDepthImageSupported == Supported.Supported)
    4.             {
    5.                 if (manager.TryAcquireEnvironmentDepthCpuImage(out var cpuImage) && cpuImage.valid)
    6.                 {
    7.                     Assert.IsTrue(cpuImage.planeCount == 1);
    8.                     var plane_data = cpuImage.GetPlane(0).data;
    9.  
    10.                     byte[] byteArray = NativeArrayToByteArray(plane_data);
    11.  
    12.                     string json = "";
    13.  
    14.                     switch (cpuImage.format)
    15.                     {
    16.                         case XRCpuImage.Format.DepthUint16:
    17.                             var temp = GetDepthEveryPoint(plane_data, cpuImage.GetPlane(0).pixelStride);
    18.                             depthToJson.list = temp;
    19.                             json = JsonUtility.ToJson(depthToJson);
    20.                             break;
    21.                         case XRCpuImage.Format.DepthFloat32:
    22.                             var f = BitConverter.ToSingle(byteArray, 0);
    23.                             break;
    24.  
    25.                     }
    26.  
    27.                     string file_name = "cpuimagedata_" + idx.ToString();
    28.  
    29.                     if (!System.IO.Directory.Exists(Application.persistentDataPath))
    30.                     {                        System.IO.Directory.CreateDirectory(Application.persistentDataPath);
    31.                     }
    32.  
    33.                     string filePath = Application.persistentDataPath + "/" + file_name + ".json";
    34.                     System.IO.File.WriteAllText(filePath, json);
    35.  
    36.                     string imagePath = Application.persistentDataPath + "/" + file_name + ".png";
    37.  
    38.                     var texture = new Texture2D(cpuImage.width, cpuImage.height, cpuImage.format.AsTextureFormat(), false);
    39.  
    40.                     var rawTextureData = texture.GetRawTextureData<byte>();
    41.                     var conversionParams = new XRCpuImage.ConversionParams(cpuImage, cpuImage.format.AsTextureFormat(), cpuImageSample.m_Transformation);
    42.                     cpuImage.Convert(conversionParams, rawTextureData);
    43.                     texture.Apply();
    44.                    
    45.                     System.IO.File.WriteAllBytes(imagePath, texture.EncodeToPNG());
    46.  
    47.                     string rgbimagePath = Application.persistentDataPath + "/" + file_name + "_rgb.png";
    48.                     Texture2D rgbTexture = depthImage.texture as Texture2D;
    49.                     System.IO.File.WriteAllBytes(rgbimagePath, rgbTexture.EncodeToPNG());
    50.  
    51.                     idx++;
    52.                 }
    53.             }
    54.         }
    55.  
    56.         List<float> GetDepthEveryPoint(NativeArray<byte> nativeArray, int pixelStride)
    57.         {
    58.             List<float> returnList = new List<float>();
    59.  
    60.             for (int i = 0; i < nativeArray.Length; i += pixelStride)
    61.             {
    62.                 var data = nativeArray.GetSubArray(i, pixelStride);
    63.                 var d = BitConverter.ToUInt16(data.ToArray(), 0) / 1000f;
    64.                 returnList.Add(d);
    65.             }
    66.  
    67.             return returnList;
    68.         }
     
  9. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    You'll need to create a vector3 for each pixel and then use the pixel's vector3 to calculate the magnitude from the screen center's vector3.
     
  10. chanmob

    chanmob

    Joined:
    Mar 28, 2016
    Posts:
    11
    I'm really sorry, but how should I implement it?
     
  11. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    510
    I've not tested it but try something like this:

    Code (CSharp):
    1.         List<float> GetDepthEveryPoint(NativeArray<byte> nativeArray, int pixelStride, int imageWidth,int imageHeight)
    2.         {
    3.             List<float> returnList = new List<float>();
    4.             float distance=0;
    5.             int x=0;
    6.             int y=0;
    7.             float viewScale=0.2f;
    8.             for (int i = 0; i < nativeArray.Length; i += pixelStride)
    9.             {
    10.                 var data = nativeArray.GetSubArray(i, pixelStride);
    11.                 var d = BitConverter.ToUInt16(data.ToArray(), 0) / 1000f;
    12.                 Vector3 pixelPosition=new Vector3((float)x-(imageWidth/2)*viewScale,(float)y-(imageHeight/2)*viewScale,(float)d);
    13.                 distance=Vector3.Magnitude(pixelPosition);
    14.                 returnList.Add(distance);
    15.                 x++;
    16.                 if (x>=imageWidth)
    17.                 {
    18.                     x=0;
    19.                     y+=1;
    20.                 }
    21.             }
    22.             return returnList;
    23.         }
    24.  
     
    Last edited: Jun 17, 2023
  12. WyattBUnity

    WyattBUnity

    Unity Technologies

    Joined:
    Mar 27, 2023
    Posts:
    31
    Could you elaborate what you mean by saying that when you used the occlusion depth system, "the center of the camera and the depth of the camera are the same even from the distance".
    In any case, I found this as a possible resource, they are saying you may have to blit the texture directly to get access to the values that they report are representing distances.
    https://forum.unity.com/threads/env...nd-depth-in-arfoundation.919076/#post-6240008