3

我正在使用 ARToolkit for android 并尝试在检测到的标记上写一个文本。我想使用一个简单的 TextView 来做到这一点。所以我只使用 ARToolkit 来查找标记。

但是我怎样才能在我的相机预览中找出标记正确的位置(我需要坐标),所以我可以将 TextView 放在标记上?

提前致谢 !

4

2 回答 2

3

两条评论都是正确的,ARToolkit 返回一个投影矩阵和一个变换矩阵。两者都设计为与 OpenGL 一起使用,而不是与标准 Android 视图一起使用。投影矩阵将应用于相机,变换矩阵将应用于对象(姿势矩阵)

如果您只想显示文本,我建议您使用 Unity 插件,然后使用 Unity UI 组件添加画布和附加到标记的文本。这些组件已经设计为 3D 对象(如果您这样做,请记住将画布设置为"World Space"

您拥有的其他选项是:

a) 将文本渲染为纹理并将其绘制在 Quad 上,您可以根据具有立方体的示例来执行此操作。

b) 使用矩阵进行一些矩阵计算,并使用转换矩阵(Android 类)对 TextView 的位置和旋转应用转换。虽然是可能的,但所涉及的数学相当复杂。如果您希望它只是漂浮在相机上,setTranslationX、Y 和 Z 就足够了。

c) 将具有文本渲染功能的 3D 引擎链接到 ARToolkit。我已经用 jPCT-AE 做到了。虽然这行得通,但它需要做很多工作。我打算很快写下来。

于 2015-08-01T04:24:31.000 回答
2

还有另一个选项可以检测标记角点。它将需要对包装代码进行一些更改并重新编译 Android 二进制文件。

fork 或克隆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;

}

毕竟,我使用 build.sh 脚本重新编译了 android 目录中的 ARWrapper 共享对象,并使用了这些新的共享对象。

在他的 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

于 2016-08-17T19:58:22.760 回答