Android ARToolkit — положение маркера

Я использую ARToolkit для Android и пытаюсь написать текст поверх обнаруженного маркера. Я хочу сделать это с помощью простого TextView. Поэтому я использую только ARToolkit, чтобы найти маркер.

Но как мне узнать, где в моей камере-превью маркера правильно нет (мне нужны координаты), поэтому я могу, но TextView поверх маркера?

Заранее спасибо !


person ossi    schedule 30.07.2015    source источник
comment
Кажется, что рядом с документацией по ARToolkit нет документации, но я предполагаю, что она следует за другими библиотеками AR - это означает, что есть возвращенная матрица поз, которую можно использовать для вычисления местоположения объекта на экране.   -  person harism    schedule 30.07.2015
comment
Метод ARToolKit.getInstance().queryMarkerTransformation(markerID) возвращает массив с плавающей запятой с 16 элементами, который в примере передается методу GL10.glLoadMatrixf. Но я не могу понять, как я могу вычислить позицию из этого массива.   -  person ossi    schedule 31.07.2015


Ответы (2)


Оба комментария верны, ARToolkit возвращает как матрицу проекции, так и матрицу преобразования. Оба предназначены для использования с OpenGL, а не со стандартным представлением Android. Матрица проекции применяется к камере, а матрица преобразования — к объекту (матрица позы).

Если вы хотите отображать только текст, я рекомендую вам использовать плагин Unity, а затем использовать компоненты пользовательского интерфейса Unity, чтобы добавить холст и текст, прикрепленный к маркеру. Эти компоненты уже спроектированы как трехмерные объекты (если вы пойдете по этому пути, не забудьте установить для холста значение "Мировое пространство".

Другие варианты, которые у вас есть:

а) Преобразуйте текст в текстуру и нарисуйте его на квадроцикле, вы можете сделать это на примере с кубом.

b) Выполните некоторые матричные вычисления, используя как матрицу, так и применение преобразований к TextView по положению и вращению с использованием матрицы преобразования (класс Android). Хотя это возможно, задействованная математика довольно сложна. Если вы хотите, чтобы он просто плавал, глядя в камеру, setTranslationX, Y и Z должно быть достаточно.

c) Связать 3D-движок с возможностью рендеринга текста с ARToolkit. Я сделал это с помощью jPCT-AE. Хотя это работает, это требует довольно много работы. Я планирую написать об этом в ближайшее время.

person shalafi    schedule 01.08.2015
comment
Можете ли вы дать мне более подробную информацию о вашей рекомендации относительно плагина Unity? Где взять этот плагин? Означает ли это, что я создаю холст с текстом в Unity3D и добавляю его в eclipse? Потому что таким образом я не мог динамически изменять текст, верно? - person ossi; 02.08.2015
comment
Что ж, единство есть единство, вы можете использовать Unity для проекта, а затем напрямую скомпилировать apk, не используя другую IDE. Теоретически вы можете экспортировать в Android и изменить код Java, но я никогда этого не делал и не знаю, сработает ли это. Плагин для единства можно загрузить со страницы загрузки artoolkit. - person shalafi; 05.08.2015
comment
после просмотра всех этих 4 вариантов использование TextView кажется мне лучшим вариантом, поскольку это даст мне максимальную гибкость и избавит меня от OpenGL. Однако я до сих пор не знаю, как получить значения для setTranslationX и setTranslationY из матрицы ARToolkit. Не могли бы вы подсказать, как может работать этот расчет? - person ossi; 12.08.2015
comment
Это не то, что я использовал сам, но я знаю, что матрица содержит информацию о положении и вращении, поскольку это матрица 4x4. Вероятно, вы можете просмотреть некоторые учебные пособия по openGL, чтобы узнать об этом. - person shalafi; 12.08.2015

Существует еще один вариант обнаружения угловых точек маркеров. Это потребует некоторых изменений в коде оболочки и перекомпиляции двоичных файлов Android.

Разветвите или клонируйте репозиторий artoolkit5 github и внесите следующие изменения:

Добавьте запись в ARMarker.h

float cornerPoints[8];

В ARMarkerSquare.cpp внесите изменения в метод updateWithDetectedMarkers сразу после того, как код, в котором маркер был определен как видимый, обновите CornerPoints:

// Consider marker visible if a match was found.
    if (k != -1) {
        visible = true;
        m_cf = markerInfo[k].cf;
        for (int c = 0; c < 4; c++) {
            cornerPoints[c*2] = markerInfo[k].vertex[c][0];
            cornerPoints[c*2 + 1] = markerInfo[k].vertex[c][1];
        }

Добавьте новый метод ARToolKitWrapperExportedAPI.cpp для получения угловых точек:

EXPORT_API bool arwQueryMarkerCornerPoints(int markerUID, float points[8])
{
 ARMarker *marker;

if (!gARTK) return false;
if (!(marker = gARTK->findMarker(markerUID))) {
    gARTK->logv(AR_LOG_LEVEL_ERROR, "arwQueryMarkerCornerPoints(): Couldn't locate marker with UID %d.", markerUID);
    return false;
}
for (int i = 0; i < 8; i++) points[i] = (float)marker->cornerPoints[i];
return marker->visible;

}

И добавьте для этого определение JNI:

JNIEXPORT jfloatArray JNICALL JNIFUNCTION(arwQueryMarkerCornerPoints(JNIEnv *env, jobject obj, jint markerUID))
{
float trans[8];

if (arwQueryMarkerCornerPoints(markerUID, trans)) return glArrayToJava(env, trans, 8);
return NULL;

}

После всего этого я перекомпилировал общие объекты ARWrapper в каталоге android с помощью скрипта build.sh и использовал эти новые общие объекты.

В NativeInterface.java добавьте следующий метод:

/**
 * Retrieves the corner points for the specified marker
 *
 * @param markerUID The unique identifier (UID) of the marker to check
 * @return A float array of size 8 containing the corner points starting at top left (x,y) top right, bottom right, bottom left.
 * So
 */
public static native float[] arwQueryMarkerCornerPoints(int markerUID);

И, наконец, добавьте метод в ARToolKit.java:

/**
 * Retrieves the corner points for the specified marker
 *
 * @param markerUID The unique identifier (UID) of the marker to check
 * @return A float array of size 8 containing the corner points starting at top left (x,y) top right, bottom right, bottom left.
 *
 */
public float[] arwQueryMarkerCornerPoints(int markerUID) {
    if (!initedNative) return null;
    return NativeInterface.arwQueryMarkerCornerPoints(markerUID);
}

Смотрите также:

https://archive.artoolkit.org/community/forums/viewtopic.php?f=26&t=16099

Изменения можно увидеть и в этом форке: https://github.com/ekkelenkamp/artoolkit5/tree/marker_corner_points

person Ekkelenkamp    schedule 17.08.2016
comment
Ответы только по ссылкам бесполезны, можете ли вы предоставить подробности? Спасибо! - person ewitkows; 17.08.2016
comment
Добавлены уточнения. - person Ekkelenkamp; 18.08.2016