3

I'm using the ARToolkit for android and try to write a text over the detected marker. I want to do this using a simple TextView. So I'm only using ARToolkit to find the marker.

But how can I find out where in my camera-preview the marker is right no (I need the coordinates), so I can but the TextView over the marker?

Thanks in advance !

Misha Akopov
  • 12,241
  • 27
  • 68
  • 82
ossi
  • 85
  • 1
  • 12
  • There seems to be next to non documentation on ARToolkit but I'd guess it follows other AR libraries - meaning there's a returned _pose matrix_ which can be used to calculate object location on screen. – harism Jul 30 '15 at 18:22
  • 1
    The ARToolKit.getInstance().queryMarkerTransformation(markerID) method returns a float-array with 16 entries, which in the example is passed to the GL10.glLoadMatrixf method. But I can't find out how I could calculate the position from this array. – ossi Jul 31 '15 at 08:09

2 Answers2

3

Both comments are correct, ARToolkit returns both a Projection Matrix and a Transformation Matrix. Both are designed to be used with OpenGL, not with a standard Android view. The projection matrix is to be applied to the camera and the transformation one is to be applied to the object (pose matrix)

If you only want to display text, I recommend you to use the Unity plugin and then use the Unity UI components to add a canvas and a text attached to the marker. Those components are already designed to be 3D objects (if you go that way, remember to set the canvas to "World Space".

The other options you have are:

a) Render the text into a texture and draw it on a Quad, you can do that based on the example that has a cube.

b) Do some matrix calculations using both matrix and the apply transformations to the TextView on position and rotation using a transformation Matrix (the Android class). Although is possible, the math involved is rather complex. If you want it to just float looking at the camera, setTranslationX, Y and Z should be enough.

c) Link a 3D engine with text rendering capability to ARToolkit. I've done that with jPCT-AE. While this works, it takes quite a lot of work. I plan to write about it soon.

shalafi
  • 3,926
  • 2
  • 23
  • 27
  • Can you give me any more details about your recommendation regarding the Unity plugin? Where do I get this plugin? Does this mean that I create the canvas with the text in Unity3D, and add it in eclipse? Because this way, I could not change the text dynamically, right? – ossi Aug 02 '15 at 08:35
  • Well, unity is unity, you can use Unity for the project and then compile an apk directly without using other IDE. You can in theory export to Android and modify the java code, but I've never done it and I don't know if it would work. The unity plugin can be downloaded from the download page of artoolkit. – shalafi Aug 05 '15 at 20:27
  • after looking at all of these 4 options, using a TextView looks like the best option to me, as it would give me the most flexibility and would save me from OpenGL. However I still don’t know how I could get the values for setTranslationX and setTranslationY out of the ARToolkit matrix. Can you give me a hint how this calculation could work? – ossi Aug 12 '15 at 09:56
  • 1
    It is not something I've used myself, but I know the matrix contains position and rotation information as it is a 4x4 matrix. You can probably look into some openGL tutorials to find about it. – shalafi Aug 12 '15 at 11:03
2

There is another option to detect the markers corner points. It will require some changes to the wrapper code and recompiling the Android binaries.

Fork or clone the artoolkit5 github repository and make the following changes:

Add an entry to ARMarker.h

float cornerPoints[8];

In ARMarkerSquare.cpp make a change in the updateWithDetectedMarkers method just after the code where a marker has been determined visible, update the 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];
        }

Add a new method ARToolKitWrapperExportedAPI.cpp to retrieve the corner points:

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;

}

And add the JNI definition for that:

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;

}

After all that I recompile the ARWrapper shared objects in the android directory with the build.sh script and used these new shared objects.

In the he NativeInterface.java add the following method:

/**
 * 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);

And finally add the method to ARToolKit.java as well:

/**
 * 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);
}

See also:

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

The changes can be seen seen in this fork as well: https://github.com/ekkelenkamp/artoolkit5/tree/marker_corner_points

Ekkelenkamp
  • 248
  • 5
  • 9