Как измерить расстояние с помощью ARCore?

Можно ли рассчитать расстояние между двумя HitResult`ами?

Или как мы можем рассчитать реальное расстояние (например, метры) с помощью ARCore?


person Alexey Podolian    schedule 31.08.2017    source источник


Ответы (3)


В Java ARCore мировыми единицами измерения являются метры (я только что понял, что мы можем не задокументировать это ... аааи выглядит как нет. Упс, сообщение об ошибке). Вычитая компонент перевода из двух Pose, вы можете получить расстояние между ними. Ваш код будет выглядеть примерно так:

При первом обращении как hitResult:

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

При втором попадании как 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);

Предполагая, что эти результаты попаданий не происходят в одном кадре, создание Anchor важно, потому что виртуальный мир может изменяться каждый раз, когда вы вызываете Session.update(). Если удерживать это место с помощью якоря, а не просто позы, его поза будет обновляться, чтобы отслеживать физические особенности в этих изменениях.

person Ian M    schedule 31.08.2017
comment
ARCore world units are meters - Отлично! Это справедливо и для Unity? - person PhilLab; 31.08.2017
comment
Только что подтвердил, что да, счетчики в Unity тоже. Unreal может быть cm или что-то в этом роде. - person Ian M; 31.08.2017

Вы можете извлечь две HitResult позы с помощью getHitPose (), а затем сравните их компонент перевода (getTranslation ()). Перевод определяется как

... вектор положения от целевой (обычно мировой) системы координат до локальной системы координат, выраженной в конечных (мировых) координатах.

Что касается физического устройства этого я не смог найти никаких замечаний. С откалиброванной камерой это должно быть математически возможно, но я не знаю, действительно ли они предоставляют API для этого.

person PhilLab    schedule 31.08.2017

Ответ: да, конечно, вы определенно можете рассчитать расстояние между двумя HitResult. Размер сетки для ARCore, как и для ARKit фреймворка, равен meters. Иногда полезнее использовать centimetres. Вот несколько способов сделать это с помощью Java и старого доброго Pythagorean theorem:

введите описание изображения здесь

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;
person Andy Fedoroff    schedule 20.09.2018
comment
Не могли бы вы поделиться своим полным кодом? Это мне очень поможет - person Shubham Agrawal; 15.10.2018
comment
Не могли бы вы помочь мне получить height объекта? Предположим, я поместил куб в определенную точку и масштабировал этот куб. Теперь окончательное значение, которое приходит, находится в векторах. У меня нет ссылки, чтобы преобразовать это в метры. - person Shubham Agrawal; 15.10.2018
comment
Почему вы умножаете на 100 (1000/10 = 100), чтобы преобразовать метры в сантиметры? Почему бы просто не сделать distanceInMeters * 100? - person kenyee; 01.11.2018
comment
Поскольку DistanceM имеет тип int, но результат делится на float. Хотя, можно как угодно посчитать))) Это вопрос точности ... - person Andy Fedoroff; 01.11.2018