aboli81
aboli81

Reputation: 3

Reading the transformation matrix from andar

I am developing an android based tracking system using camera and other sensors on android. I am interested in reading the transformation matrix from AndAR rather than displaying some object (e.g. a cube) when the marker is detected. I have another tracking system developed using a flavor of ARToolkit, called jARToolkit, that runs on desktop machine and gives transformation matrix between the web-camera and the pattern. Right now I am getting the transformation matrix from AndAR, but if we compare it with the transformation matrix that I am getting from jARToolkit, it is totally different. The reason could be following problems -

  1. The surface preview that I see on android is always rotated by 90 degrees. So my X and Y co-ordinates in the translation matrix exchange their position.
  2. I am not sure about the unit of the translation matrix. It comes to around 4 units per cm in physical world but there is no way for me to verify this.

I would appreciate if anyone could help me to address these questions or let me know if I am missing something. Thanks in advance.

Following is the code that I am using. It is pretty much the same as in the AndAR documentation.

boolean keepRunning = true;
try {
    ARToolkit artoolkit = getArtoolkit();
    CustomObject object_hiro = new CustomObject("test_hiro", "hiro.patt", 80.0,new double[] { 0, 0 });
    artoolkit.registerARObject(object_hiro);
}
catch (AndARException ex)
{       
    System.out.println("");
}
while(keepRunning)
{
    double[] transMatrix = (double[]) object_hiro.getTransMatrix();
}

and here is the CustomObject.java -

import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import edu.dhbw.andar.ARObject;
import edu.dhbw.andar.pub.SimpleBox;
import edu.dhbw.andar.util.GraphicsUtil;

/**
 * An example of an AR object being drawn on a marker.
 * @author tobi
 *
 */
public class CustomObject extends ARObject {

    public CustomObject(String name, String patternName,
            double markerWidth, double[] markerCenter) {
        super(name, patternName, markerWidth, markerCenter);
        float   mat_ambientf[]     = {0f, 1.0f, 0f, 1.0f};
        float   mat_flashf[]       = {0f, 1.0f, 0f, 1.0f};
        float   mat_diffusef[]       = {0f, 1.0f, 0f, 1.0f};
        float   mat_flash_shinyf[] = {50.0f};

        mat_ambient = GraphicsUtil.makeFloatBuffer(mat_ambientf);
        mat_flash = GraphicsUtil.makeFloatBuffer(mat_flashf);
        mat_flash_shiny = GraphicsUtil.makeFloatBuffer(mat_flash_shinyf);
        mat_diffuse = GraphicsUtil.makeFloatBuffer(mat_diffusef);

    }
    public CustomObject(String name, String patternName,
            double markerWidth, double[] markerCenter, float[] customColor) {
        super(name, patternName, markerWidth, markerCenter);
        float   mat_flash_shinyf[] = {50.0f};
        mat_ambient = GraphicsUtil.makeFloatBuffer(customColor);
        mat_flash = GraphicsUtil.makeFloatBuffer(customColor);
        mat_flash_shiny = GraphicsUtil.makeFloatBuffer(mat_flash_shinyf);
        mat_diffuse = GraphicsUtil.makeFloatBuffer(customColor);

    }

    private SimpleBox box = new SimpleBox();
    private FloatBuffer mat_flash;
    private FloatBuffer mat_ambient;
    private FloatBuffer mat_flash_shiny;
    private FloatBuffer mat_diffuse;


    /**
     * Everything drawn here will be drawn directly onto the marker,
     * as the corresponding translation matrix will already be applied.
     */
    @Override
    public final void draw(GL10 gl) {       
        super.draw(gl);
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR,mat_flash);
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, mat_flash_shiny);    
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, mat_diffuse);  
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, mat_ambient);

        //draw cube
        gl.glColor4f(1.0f, 0f, 0, 1.0f);
        gl.glTranslatef( 0.0f, 0.0f, 12.5f );

        box.draw(gl);      
    }

    @Override
    public void init(GL10 gl) {
        // TODO Auto-generated method stub

    }
}

Please let me know if I need to provide additional information.. Thanks

Upvotes: 0

Views: 817

Answers (1)

Raphael Grasset
Raphael Grasset

Reputation: 152

Original C ARToolKit has two type of transformation associated to a marker:

  • a 3x4 matrix (computer vision matrix from the pose estimation, obtained from arGetTransMat)

  • a 4x4 matrix (an OpenGL-like matrix, obtained from argConvGLcpara with the above 3x4 matrix).

In AndAR:

  • 3x4 matrix: can be obtained by calling getTransMatrix() from your ARObject.
  • 4x4 matrix: not publicly accessible from your ARObject, matrix stored in glCameraMatrix (see the code of ARObject.java).

in JARToolKit:

  • 3x4 matrix: can be obtained by calling getTransMatrix
  • 4x4 matrix: can be obtained by calling getCamTransMatrix

Maybe you access a different matrix between AndAR and JARToolKit.

The unit is relative to your marker size. Generally it's in mm, parameter in your declaration of object_hiro: 80.0 represents 80mm width. You can print your marker to this size so you get a match between your physical object and virtual content.

Upvotes: 0

Related Questions