首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AR相机测距

AR相机测距
EN

Stack Overflow用户
提问于 2021-01-08 12:19:22
回答 3查看 696关注 0票数 0

我有一个关于AR(增强现实)的问题。

我想知道如何显示距离信息(如中心仪...)AR相机和目标对象之间的距离。(使用智能手机)

我可以在Unity中这样做吗?我应该使用AR Foundation吗?那ARcore呢?如何编写代码?

我试着找到一些相关的代码(如下),但它似乎只是打印对象和对象之间的信息,没有关于"AR相机“…

代码语言:javascript
复制
var other : Transform;
if (other) {
    var dist = Vector3.Distance(other.position, transform.position);
    print ("Distance to other: " + dist);
}

再次感谢!

EN

回答 3

Stack Overflow用户

发布于 2021-04-23 20:48:06

下面是Unity和AR Foundation 4.1的使用方法。此示例脚本在depth纹理的中心打印以米为单位的深度,并同时适用于ARCore和ARKit:

代码语言:javascript
复制
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;


public class GetDepthOfCenterPixel : MonoBehaviour {
    // assign this field in inspector
    [SerializeField] AROcclusionManager manager = null;
    
    
    IEnumerator Start() {
        while (ARSession.state < ARSessionState.SessionInitializing) {
            // manager.descriptor.supportsEnvironmentDepthImage will return a correct value if ARSession.state >= ARSessionState.SessionInitializing 
            yield return null;
        }
        
        if (!manager.descriptor.supportsEnvironmentDepthImage) {
            Debug.LogError("!manager.descriptor.supportsEnvironmentDepthImage");
            yield break;
        }
        
        while (true) {
            if (manager.TryAcquireEnvironmentDepthCpuImage(out var cpuImage) && cpuImage.valid) {
                using (cpuImage) {
                    Assert.IsTrue(cpuImage.planeCount == 1);
                    var plane = cpuImage.GetPlane(0);
                    var dataLength = plane.data.Length;
                    var pixelStride = plane.pixelStride;
                    var rowStride = plane.rowStride;
                    Assert.AreEqual(0, dataLength % rowStride, "dataLength should be divisible by rowStride without a remainder");
                    Assert.AreEqual(0, rowStride % pixelStride, "rowStride should be divisible by pixelStride without a remainder");

                    var numOfRows = dataLength / rowStride;
                    var centerRowIndex = numOfRows / 2;
                    var centerPixelIndex = rowStride / (pixelStride * 2);
                    var centerPixelData = plane.data.GetSubArray(centerRowIndex * rowStride + centerPixelIndex * pixelStride, pixelStride);
                    var depthInMeters = convertPixelDataToDistanceInMeters(centerPixelData.ToArray(), cpuImage.format);
                    print($"depth texture size: ({cpuImage.width},{cpuImage.height}), pixelStride: {pixelStride}, rowStride: {rowStride}, pixel pos: ({centerPixelIndex}, {centerRowIndex}), depthInMeters of the center pixel: {depthInMeters}");
                }
            }
            
            yield return null;
        }
    }

    float convertPixelDataToDistanceInMeters(byte[] data, XRCpuImage.Format format) {
        switch (format) {
            case XRCpuImage.Format.DepthUint16:
                return BitConverter.ToUInt16(data, 0) / 1000f;
            case XRCpuImage.Format.DepthFloat32:
                return BitConverter.ToSingle(data, 0);
            default:
                throw new Exception($"Format not supported: {format}");
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2021-01-08 16:46:39

我也在做AR深度图像,基本的想法是:

  1. Acquire一个图像使用接口,通常它的格式是将图像到短缓冲区,因为Depth16意味着每个像素是16个短缓冲区的距离值,这是存储在每个短缓冲区的低13位,你可以这样做( Depth16;
  2. Split & 0x1ff),然后你就可以得到每个像素的距离,通常是在millimeters.

通过对所有像素执行此操作,您可以创建深度图像并将其存储为jpg或其他格式,以下是使用AR引擎获取距离的示例代码:

代码语言:javascript
复制
try (Image depthImage = arFrame.acquireDepthImage()) {
        int imwidth = depthImage.getWidth();
        int imheight = depthImage.getHeight();
        Image.Plane plane = depthImage.getPlanes()[0];
        ShortBuffer shortDepthBuffer = plane.getBuffer().asShortBuffer();
        File sdCardFile = Environment.getExternalStorageDirectory();
        Log.i(TAG, "The storage path is " + sdCardFile);
        File file = new File(sdCardFile, "RawdepthImage.jpg");

        Bitmap disBitmap = Bitmap.createBitmap(imwidth, imheight, Bitmap.Config.RGB_565);
        for (int i = 0; i < imheight; i++) {
            for (int j = 0; j < imwidth; j++) {
                int index = (i * imwidth + j) ;
                shortDepthBuffer.position(index);
                short depthSample = shortDepthBuffer.get();
                short depthRange = (short) (depthSample & 0x1FFF);
                //If you only want the distance value, here it is
                byte value = (byte) depthRange;
          byte value = (byte) depthRange ;
                disBitmap.setPixel(j, i, Color.rgb(value, value, value));
            }
        }
        //I rotate the image for a better view
        Matrix matrix = new Matrix();
        matrix.setRotate(90);
        Bitmap rotatedBitmap = Bitmap.createBitmap(disBitmap, 0, 0, imwidth, imheight, matrix, true);

        try {
            FileOutputStream out = new FileOutputStream(file);
            rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
            out.flush();
            out.close();
            MainActivity.num++;
        } catch (Exception e) {
            e.printStackTrace();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
票数 0
EN

Stack Overflow用户

发布于 2021-05-10 09:19:10

虽然答案很好,但对于这个问题来说,它们可能太复杂和高级了,这个问题是关于ARCamera和另一个对象之间的距离,而不是关于像素的深度和它们的遮挡。

transform.position为您提供在层次中附加脚本的任何游戏对象的位置。因此,将脚本附加到ARCamera对象。显然,other应该是目标对象。

或者,您可以使用检查器变量或GetComponent获取对这两个游戏对象的引用

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65623402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档