web-dev-qa-db-ja.com

ARCoreを使用して距離を測定する方法は?

2つのHitResult `間の距離を計算することは可能ですか?

または、ARCoreを使用して実際の距離(メートルなど)を計算する方法はありますか?

17
Alexey Podolian

In Java ARCoreワールドユニットはメートルです(これを文書化しないかもしれないことに気付きました... aaaand nope。Oops、bug filed)。翻訳を差し引くことで2つのPosesのコンポーネントを使用すると、それらの間の距離を取得できます。コードは次のようになります。

hitResultとして最初にヒットしたとき:

_startAnchor = session.addAnchor(hitResult.getHitPose());
_

hitResultとしての2回目のヒット:

_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);
_

これらのヒット結果が同じフレームで発生しないと仮定すると、Session.update()を呼び出すたびに仮想世界を再形成できるため、Anchorを作成することが重要です。ポーズの代わりにアンカーでその場所を保持することにより、そのポーズは更新され、それらの再形成全体の物理的特徴を追跡します。

26
Ian M

getHitPose() を使用して2つのHitResultポーズを抽出し、それらの翻訳コンポーネントを比較できます( getTranslation() )。翻訳は次のように定義されます

...目的地(通常は世界)座標フレームから目的地(世界)座標で表されるローカル座標フレームへの位置ベクトル。

これの物理的な単位に関しては、私は何の発言も見つけることができませんでした。キャリブレーションされたカメラでは、これは数学的に可能ですが、実際にこのためのAPIを提供しているかどうかはわかりません

3
PhilLab

答えは:はい、もちろん、2つのHitResultの間の距離を確実に計算できます。 ARCoreおよびARKitフレームワークのグリッドのサイズは、metersです。場合によっては、centimetresを使用する方が便利な場合があります。 Java and 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

または、代わりに、次の数学を使用できます。

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;
2
ARGeo