java 如何使用 ARCore 测量距离?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45982196/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 09:00:35  来源:igfitidea点击:

How to measure distance using ARCore?

javaandroidaugmented-realityarcore

提问by Alexey Podolian

Is it possible to calculate distance between two HitResult`s ?

是否可以计算两个HitResult`s之间的距离?

Or how we can calculate real distance (e.g. meters) using ARCore?

或者我们如何使用 ARCore 计算实际距离(例如米)?

回答by Ian M

In Java ARCore world units are meters (I just realized we might not document this... aaaand looks like nope. Oops, bug filed). By subtracting the translation component of two Poses you can get the distance between them. Your code would look something like this:

在 Java ARCore 中,世界单位是米(我刚刚意识到我们可能不会记录这个...... aaa 看起来不像。 哎呀,提交了错误)。通过减去两个Poses的平移分量,您可以得到它们之间的距离。你的代码看起来像这样:

On first hit as hitResult:

在第一次点击为hitResult

startAnchor = session.addAnchor(hitResult.getHitPose());

On second hit as hitResult:

在第二次命中为hitResult

Pose startPose = startAnchor.getPose();
Pose endPose = hitResult.getHitPose();

// Clean up the anchor
session.removeAnchors(Collections.singleton(startAnchor));
startAnchor = null;

// Compute the difference vector between the two hit locations.
float dx = startPose.tx() - endPose.tx();
float dy = startPose.ty() - endPose.ty();
float dz = startPose.tz() - endPose.tz();

// Compute the straight-line distance.
float distanceMeters = (float) Math.sqrt(dx*dx + dy*dy + dz*dz);

Assuming that these hit results don't happen on the same frame, creating an Anchoris important because the virtual world can be reshaped every time you call Session.update(). By holding that location with an anchor instead of just a Pose, its Pose will update to track the physical feature across those reshapings.

假设这些命中结果不会发生在同一帧上,创建一个Anchor很重要,因为每次调用Session.update(). 通过使用锚点而不是仅姿势保持该位置,其姿势将更新以跟踪这些重塑中的物理特征。

回答by PhilLab

You can extract the two HitResultposes using getHitPose()and then compare their translation component (getTranslation()). The translation is defined as

您可以HitResult使用getHitPose()提取两个姿势,然后比较它们的翻译组件 ( getTranslation())。翻译定义为

...the position vector from the destination (usually world) coordinate frame to the local coordinate frame, expressed in destination (world) coordinates.

...从目标(通常是世界)坐标系到本地坐标系的位置向量,以目标(世界)坐标表示。

As for the physical unit of this I could not find any remark. With a calibrated camera this should be mathematically possible but I don't know if they actually provide an API for this

至于这个的物理单位,我找不到任何评论。使用校准的相机,这在数学上应该是可能的,但我不知道他们是否真的为此提供了 API

回答by Andy

The answer is: Yes, of course, you definitely can calculate distance between two HitResult's. The grid's size for ARCore, as well as for ARKitframework, is meters. Sometimes, it's more useful to use centimetres. Here are a few ways how you do it with Java and great old Pythagorean theorem:

答案是:是的,当然,你绝对可以计算出两个之间的距离HitResult。的网格大小ARCore以及ARKit框架的大小为meters。有时,使用centimetres. 以下是使用 Java 和 Great old 执行此操作的几种方法Pythagorean theorem

enter image description here

在此处输入图片说明

import com.google.ar.core.HitResult

MotionEvent tap = queuedSingleTaps.poll();
if (tap != null && camera.getTrackingState() == TrackingState.TRACKING) {
    for (HitResult hit : frame.hitTest(tap)) {
        // Blah-blah-blah...
    }
}

// Here's the principle how you can calculate the distance  
// between two anchors in 3D space using Java:

private double getDistanceMeters(Pose pose0, Pose pose1) {

    float distanceX = pose0.tx() - pose1.tx();
    float distanceY = pose0.ty() - pose1.ty();
    float distanceZ = pose0.tz() - pose1.tz();

    return Math.sqrt(distanceX * distanceX + 
                     distanceY * distanceY + 
                     distanceZ * distanceZ);
} 

// Convert Meters into Centimetres

double distanceCm = ((int)(getDistanceMeters(pose0, pose1) * 1000))/10.0f;

// pose0 is the location of first Anchor
// pose1 is the location of second Anchor

Or, alternatively, you can use the following math:

或者,您也可以使用以下数学公式:

Pose pose0 = // first HitResult's Anchor
Pose pose1 = // second HitResult's Anchor

double distanceM = Math.sqrt(Math.pow((pose0.tx() - pose1.tx()), 2) + 
                             Math.pow((pose0.ty() - pose1.ty()), 2) +
                             Math.pow((pose0.tz() - pose1.tz()), 2));

double distanceCm = ((int)(distanceM * 1000))/10.0f;