Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Detecting Markers With AR Toolkit Plus

Name: Genius 2013-03-14 3:22

Appendix 1 – Detecting multiple markers with the AR Toolkit Plus

This is not to be mistaken for multi-markers, which is a different thing altogether, but allows more than 1 marker and position to be detected. This is necessary if AR applications use more than 1 marker because the AR Toolkit Plus: build 2.1.1 only returns 1 marker id and its position matrix.
The key idea is to get access to the low-level marker data by using the extra parameters in calc and making sure enough memory is allocated for all the markers with Init. You then process the marker data manually to extract out the markers.
In the code below, m_Tracker is of type ARToolKitPlus::TrackerSingleMarker. The stl list m_MarkerData collects data on each marker, including a flag to hide or show it.  The updatematrix flag in the calc function is set to false to avoid re-computing it twice since this is done with calcOpenGLMatrixFromMarker.

Sample code:

// New general multiple marker tracker code. Avoids processing video frame multiple times
ARToolKitPlus::ARMarkerInfo *markerinfo;
int nummarkers;
// Do not calculate opengl matrix (set nUpdateMatrix to false) since it is done manually
m_Tracker->calc(data,-1,false,&markerinfo,&nummarkers);

int size = m_MarkerData.size();
for (int c = 0; c < size; c++) {
int k = -1;
for (int m = 0; m < nummarkers; m++) {
if (markerinfo[m].id == c) {                                               if (k == -1)
                         k = m;
             else if (markerinfo[k].cf < markerinfo[m].cf)
                       k = m;
                   }
             }
if (k == -1) { // no marker found
                                       m_MarkerData[c].m_Visible = false;
                               }
                               else { // marker found
                                       m_MarkerData[c].m_Visible = true;
                                       m_MarkerData[c].m_Confidence = markerinfo[k].cf;
                                 ARFloat center[2] = {0.0f,0.0f};
                                       ARFloat patttrans[3][4];

m_Tracker->calcOpenGLMatrixFromMarker(&markerinfo[k],center,m_MarkerData[c].
m_Width,(ARFloat *)m_MarkerData[c].m_ModelViewMat);
       } // end markers
 
Appendix 2 – AR Toolkit Performance Benchmarks
(Source: http://www.hitl.washington.edu/artoolkit/documentation/benchmark.htm#comparison)
some value of measured accuracy of ARToolKit, jitter problems, CPU dependencies,etc... (from Kato or Billinghurst course notes).

Appendix 3 – Computation Time in relation to the angle at which markers are viewed
 

Appendix 4 – Project Settings for AR Toolkit in Windows Visual Studio 2003 .NET


1) Tools → Options → Projects → VC++ Directories

a) Select Include files and add the include directories (containing the header files) of:
i) AR Toolkit
ii) OpenVRML (should be in AR Toolkit directory)
iii) OpenVRML dependencies

If OpenAL sound is used as in “Solar System”,

iv)OpenAL

If AR Toolkit Plus is used

v) AR Toolkit Plus

b) Select Library files and add the lib directories (containing the library, .lib files) of:

i) AR Toolkit
ii) OpenVRML
iii)OpenVRML dependencies

If OpenAL sound is used:

iv) OpenAL

If AR Toolkit Plus is used:

v)AR Toolkit Plus – win32 folder

3) In addition to the above, it is also necessary to place the relevant DLL files in the same directory as the AR application executable. Any data files like camera parameters, vrml files and marker patterns must be placed according to how they are coded.

Name: Appendix 5 Continue 2013-03-14 3:23


Appendix 5 – code snippets for “Solar System”

Sound.c
#include "mrSound.h"

#define SCALE 0.005 * soundScale

float soundScale = 1;
int sourceNum = 18 ;

  ALfloat zeroes[] = { 0.0f, 0.0f,  0.0f };
  ALuint boom[MAX_SOURCE_NUM];
  ALsizei size;
  //ALsizei bits;
  ALsizei freq;
  ALenum        format;
  ALvoid        *data;
  ALboolean    loop;
  //ALsizei format;
  ALboolean err;

// sound initialization

int alinit()
{
  int i;
  char *soundFiles[] =
    {
      "sound/get1_new.wav", //looping //0
      "sound/drop4.wav",          //1
      "sound/move1.wav",          //2
      "sound/delete1.wav",        //3
      "sound/pagechange.wav",     //4 
      "sound/exploStd.wav",       //5
      "sound/action.wav",         //6
       "sound/Cheers.wav",        //7
        "sound/hrn05.wav",        //8
        "sound/water.wav",        //9
         "sound/wood.wav",      //10
        "sound/metal.wav",        //11
        "sound/plastic.wav",      //12
        "sound/plant.wav",        //13
        "sound/excellent.wav",    //14
        "sound/well_done.wav",     //15
        "sound/fantastic.wav",    //16
        "sound/wrong.wav"       //17
    };
 

  /* Initialize ALUT. */
  alutInit(NULL, NULL);

  alGenBuffers( sourceNum, boom );
  alGenSources( sourceNum, source);

  for (i=0; i < sourceNum; i++)
    {
      //wave[i] = NULL;
        //printf("sound %d\n",i);

      alutLoadWAVFile(soundFiles[i], &format, &data, &size, &freq, &loop);
      //err = alutLoadWAV(soundFiles[i], &wave[i], &format, &size, &bits, &freq);
      // File?  no LoadWAV found
      if(err == AL_FALSE) {
    fprintf(stderr, "Could not open %s\n", soundFiles[i]);
    soundFlag = 0;
    return -1;
      }

    soundFlag = 1;

    alBufferData( boom[i], format, data, size, freq );
    free(data); /* openal makes a local copy of wave data */
 
    alSourcefv(source[i], AL_POSITION, zeroes );
    alSourcei( source[i], AL_BUFFER, boom[i] );

    alSourcef( source[i], AL_REFERENCE_DISTANCE, 1);
    }

  alListenerfv(AL_VELOCITY, zeroes );
    return 0;
}


void playBackgroundSound(ALuint sourceId, float maxGain)
{
 
  float sourceState;
  ALfloat lp[3] = { 0.0f, 0.0f,  0.0f };
  //  ALfloat sp[] = { 0.0f, 0.0f,  5.0f };

  if ( !soundFlag ) return;

  alGetListenerfv( AL_POSITION, lp );
  //alListenerfv( AL_POSITION, lp );
  alSourcef( source[sourceId], AL_MAX_GAIN, maxGain ); //decrease volume
  alSourcefv( source[sourceId], AL_POSITION, lp );


  alGetSourcef( source[sourceId], AL_SOURCE_STATE, &sourceState);

  if (sourceState != AL_PLAYING )
    alSourcePlay( source[sourceId] );
}

In the main function:
To play a sound:
    playBackgroundSound(0,1);
where 0 corresponds to the id of the sound file (first file initialized, in this case, this is get1_new.wav
and 1 controls the volume of the sound played.

For the serial port:

Within the init function:

     switch (Baud_Rate)
      {
         case 38400:
         default:
            BAUD = CBR_38400;
            break;
         case 19200:
            BAUD  = CBR_19200;
            break;
         case 9600:
            BAUD  = CBR_9600;
            break;
         case 4800:
            BAUD  = CBR_4800;
            break;
         case 2400:
            BAUD  = CBR_2400;
            break;

         case 1200:
            BAUD  = CBR_1200;
            break;
         case 600:
            BAUD  = CBR_600;
            break;
         case 300:
            BAUD  = CBR_300;
            break;
 
         case 110:
            BAUD  = CBR_110;
            break;

      }  //end of switch baud_rate

      //switch (Data_Bits)
      //{
      //  case 8:
      //   default:
      //      DATABITS = CS8;
      //      break;
      //   case 7:
      //      DATABITS = CS7;
      //      break;
      //   case 6:
      //      DATABITS = CS6;
      //      break;
      //   case 5:
      //      DATABITS = CS5;
      //      break;
      //}  //end of switch data_bits

      switch (Stop_Bits)
      {
         case 1:
         default:
            STOPBITS = ONESTOPBIT;
            break;
         case 2:
            STOPBITS = 0;
            break;
      }  //end of switch stop bits

      switch (Parity)
      {
         case 0:
         default:                       //none
            PARITY      = NOPARITY;
            PARITYON     = 0;
           
            //PARITYON = 0;
            //PARITY = 0;
            break;
         case 2:                        //odd
            PARITY     = EVENPARITY;
            PARITYON     = 1;
            //PARITYON = PARENB;
            //PARITY = PARODD;
            break;
         case 1:                        //even
            PARITY     = ODDPARITY;
            PARITYON     = 1;

            //PARITYON = PARENB;
            //PARITY = 0;
            break;
      }  //end of switch parity
     
  // initializing comm part

     hCom = CreateFile( pcCommPort,
                     GENERIC_READ | GENERIC_WRITE,
                     0,    // comm devices must be opened w/exclusive-access
                     NULL, // no security attributes
                     OPEN_EXISTING, // comm devices must use OPEN_EXISTING
                     0,    // not overlapped I/O
                     NULL  // hTemplate must be NULL for comm devices
                     );

    if (hCom == INVALID_HANDLE_VALUE) {
      // Handle the error.
      printf ("CreateFile failed with error %d.\n", GetLastError());
      return (1);
    }
    fSuccess = GetCommState(hCom, &dcb);
    if (!fSuccess) {
      // Handle the error.
      printf ("GetCommState failed with error %d.\n", GetLastError());
      return (2);
    }
 // Fill in the DCB: baud=9600 bps, 8 data bits, no parity, and 1 stop bit.
  dcb.BaudRate = BAUD;     // set the baud rate
  dcb.ByteSize = Data_Bits;             // datta size, xmit, and rcv
  dcb.Parity = PARITY;        // no parity bit
  dcb.StopBits = STOPBITS;    // one stop bit
  dcb.fParity = PARITYON;

  fSuccess = SetCommState(hCom, &dcb);
  if (!fSuccess) {
      // Handle the error.
      printf ("SetCommState failed with error %d.\n", GetLastError());
      return (3);
    }

Within the mainloop() function:
    buttonResult = ReadFile(hCom, &n,1, &nBytesRead, NULL) ;

    if(buttonResult!=0){

        if (n=='C') {
            stageInfo->activeStage++;
            subStage = 0;
            earthLayer = 0;
            if( stageInfo->activeStage >= stageInfo->stagenum ) {
                stageInfo->activeStage = 0;
                for (i=1; i<9; i++)  // don't include pluto
                    itemsInfo->item[i].distActive = 0;
            }
            for (i=0; i<3; i++) {
                potItemInfo[i].item      = -1;
                potItemInfo[i].angle     = 0;
            }
            zoominCount = 1.0;
            //zoomoutCount = 5.0;
            zoomoutCount = 100.0;
     
            if(stageInfo->activeStage == 4){
      
                srand((unsigned)time (NULL));      //seed reandom no with current time so that no will be different
                                          //everytime we run
                Quiz = (rand()%8 + 1);    // don't include pluto
                printf("generate Quiz = %d\n", Quiz);
            }
        }
    //else if (strcmp(buf,"A")==0) {
        else if (n=='A') {
            subStage ++;
            earthLayer = 0;
            for (i=0; i<3; i++) {
                potItemInfo[i].item      = -1;
                potItemInfo[i].angle     = 0;
            }
            zoominCount = 1.0;
            //zoomoutCount = 5.0;
            zoomoutCount = 100.0;
     
            }
    //else if (strcmp(buf,"B")==0) {
        else if (n=='B') {
            subStage --;
            earthLayer = 0;
            for (i=0; i<3; i++) {
                potItemInfo[i].item      = -1;
                potItemInfo[i].angle     = 0;
            }   
            zoominCount = 1.0;
            //zoomoutCount = 5.0;
            zoomoutCount = 100.0;
        }

Name: Appendix 6 Continue 2013-03-14 3:27

Appendix 6 – Initializing the AR Toolkit Plus tracker

In the init function:
tracker = new ARToolKitPlus::TrackerSingleMarkerImpl<6,6,6, 1, 20>(xsize,ysize);

    if(!tracker->init(nCamParamFile, "data/markerboard.cfg", 50.0f, 1000.0f))            // load std. ARToolKit camera file
       {
        printf ("ERROR: init() failed\n");
        //delete cameraBuffer;
        delete tracker;
    }

    tracker->setPatternWidth(80);
    tracker->setBorderWidth(0.250f);
    tracker->setUndistortionMode(ARToolKitPlus::UNDIST_STD);
    tracker->setPixelFormat(ARToolKitPlus::PIXEL_FORMAT_BGRA);
    tracker->setMarkerMode(ARToolKitPlus::MARKER_ID_SIMPLE);
    tracker->activateAutoThreshold(true);

The above code creates an AR Toolkit Plus tracker that detects simple id markers that have a width of 80mm and a ¼ border. It also enables the auto-thresholding feature.
In the mainloop function
markerId = tracker2->calc((unsigned char*)dataPtr);
if (markerId == 0)
    draw();
The calc function returns an id of the marker detected and if it corresponds to id 0, an overlay will be drawn over the marker. Refer to appendix 1 if multiple markers are to be detected.

Name: Holy Shit 2013-03-14 13:32

This post should be given the best thread award of all the /prog/

Name: Anonymous 2013-03-15 1:43

>>1-3
How do I integrate it with Google+, Twitter and the cloud so that personal information including GPS coordinates is safely stored forever in a searchable database?

Don't change these.
Name: Email:
Entire Thread Thread List