Search Unity

Question No CameraManager configurations?

Discussion in 'AR' started by ivoras, May 26, 2021.

  1. ivoras

    ivoras

    Joined:
    May 21, 2020
    Posts:
    66
    Hello,

    I'm trying to use CameraManager.TryAcquireLatestCpuImage to get a raw camera image on an AR Foundation app, in order to search QR codes in the image. To do so, it must not be obscured by 3D / AR objects.

    My default, on Android, the resulting image is of 640x480 resolution, which isn't enough to recognize QR codes from a desired distance.

    I've followed advice given in this thread: https://forum.unity.com/threads/how-to-get-camera-texture-in-arfoundation.543827/ and tried to search CameraManager configurations for a resolution which would suit this purpose.

    Unfortunately, calling:

    Code (CSharp):
    1. CameraManager.GetConfigurations(Allocator.Temp)
    Results in an array of 0 length (on Samsung S21).

    The purpose here isn't to manipulate the AR camera's resolution, just to get a copy of the camera frame without it being downscaled to 640x480.

    How do I do that?

    Unfortunately, the example given in the above link doesn't work because CameraManager.material is null (and I don't know how would the RenderTexture be constructed in any case, in which resolution?).
     
    Last edited: May 26, 2021
  2. ivoras

    ivoras

    Joined:
    May 21, 2020
    Posts:
    66
    Ok, I figured out that CameraManager configurations only become available after the first frame is drawn.

    I hope it's obvious that it's an architectural mistake somewhere.

    However, after I select my configuration on the first frame, like this:

    Code (CSharp):
    1.     void onFrameReceived(ARCameraFrameEventArgs a) {
    2.         CameraManager.frameReceived -= onFrameReceived;
    3.  
    4.         var selectedCfg = CameraManager.currentConfiguration;
    5.         using (var configurations = CameraManager.GetConfigurations(Allocator.Temp))
    6.         {
    7.             if (!configurations.IsCreated || (configurations.Length <= 0))
    8.             {
    9.                 RLog.Log(this.name, $"Bailing out from CameraManager configurations: {configurations.IsCreated} {configurations.Length}");
    10.                 return;
    11.             }
    12.             foreach (var config in configurations) {
    13.                 if (config.width >= 1000 && config.width <= 2000) {
    14.                     selectedCfg = config;
    15.                     break;
    16.                 }
    17.             }
    18.         }
    19.         if (selectedCfg != CameraManager.currentConfiguration) {
    20.             CameraManager.currentConfiguration = selectedCfg;
    21.             RLog.Log(this.name, $"Setting CameraManager.currenetConfiguration to {selectedCfg?.width}x{selectedCfg?.height}");
    22.         }
    23.     }
    24.  
    I see the camera reinitialising on the mobile device. There's several milliseconds of black screens been drawn after the first frame is drawn.

    That's a pretty bad UX. Can it be avoided?

    The whole thing seems very weird. Why is the initial configuration the one which gives me 640x480 images? Why is the camera being reinitialised after the configuration is set? I don't think the camera feed which is visible on the device changes resolution, but I can't be sure of that...
     
    KyryloKuzyk likes this.
  3. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,822
    Note from the team: The behavior is how Android ARCore operates.