Logo Mon Club Elec

Processing – ARToolkit : Second essai utilisant ARToolkit et la réalité augmentée

Processing et ARToolkit sont deux outils puissants qui permettent aux développeurs de créer des applications de réalité augmentée. Dans ce deuxième essai, nous allons explorer comment ces deux outils peuvent être utilisés ensemble pour créer des expériences interactives et immersives. Nous allons voir comment Processing et ARToolkit peuvent être combinés pour créer des applications de réalité augmentée qui peuvent être utilisées pour des fins commerciales, éducatives et artistiques. Nous allons également examiner les avantages et les inconvénients de cette combinaison et discuter des possibilités qu’elle offre.

Processing – ARToolkit : Second essai utilisant ARToolkit et la réalité augmentée

Par X. HINAULT – 15 Février 2012

Processing – ARToolkit : Second essai utilisant ARToolkit et la réalité augmentée

L’image après reconnaissance des markers et tracé 3D

Explication

Matériel et configuration utilisés

  • PC Intel Core Quad 2.33 Ghz
  • Webcam(s) USB C270
  • Ubuntu 10.04 LTS
  • Processing 1-5
  • Librairie GSVideo 0.9
  • nyar4psg 1.1.7

Ressources utiles

Le programme

Copier / coller ce code dans Processing L’image de test utilisée est en ligne !
Ne pas oublier de modifier les chemins utilisés en fonction de votre situation.

// Augmented Reality Dynamic Example by Amnon Owed (21/12/11)
// Processing 1.5.1 + NyARToolkit 1.1.6 + GSVideo 1.0

import java.io.*; // for the loadPatternFilenames() function
import processing.opengl.*; // for OPENGL rendering
import jp.nyatla.nyar4psg.*; // the NyARToolkit Processing library
import codeanticode.gsvideo.*; // the GSVideo library

// a central location is used for the camera_para.dat and pattern files, so you don’t have to copy them to each individual sketch
// Make sure to change both the camPara and the patternPath String to where the files are on YOUR computer
// the full path to the camera_para.dat file
//String camPara = « C:/Users/mainframe/Documents/Processing/libraries/nyar4psg/data/camera_para.dat »;
// the full path to the .patt pattern files
//String patternPath = « C:/Users/mainframe/Documents/Processing/libraries/nyar4psg/patternMaker/examples/ARToolKit_Patterns »;

//—– chemin absolu fichier de paramètres de distorsion de la camera —-
//String camParaPath = « /home/hinault/Téléchargements/librairies_processing/nyar4psg-1.1.6/data/camera_para.dat »;
String camParaPath = « /home/hinault/Téléchargements/processing-1.5/modes/java/libraries/NyAR4psg/data/camera_para.dat »;

//—– chemin absolu fichiers de description des « patterns » ou « markers » —-
String patternPath = « /home/hinault/Téléchargements/patternMaker/examples/ARToolKit_Patterns »;
// l’archive patternMaker est disponible ici : http://www.cs.utah.edu/gdc/projects/augmentedreality/download.html

// the dimensions at which the AR will take place. with the current library 1280×720 is about the highest possible resolution.
int arWidth = 640;
int arHeight = 360;

int widthCapture=640;
int heightCapture=480;

int fpsCapture=20;

// the number of pattern markers (from the complete list of .patt files) that will be detected, here the first 10 from the list.
int numMarkers = 3;
String[] nameMarkers= new String[numMarkers]; // pour mémoriser le nom des marker

// the resolution at which the mountains will be displayed
int resX = 60;
int resY = 60;
// this is a 2 dimensional float array that all the displayed mountains use during their update-to-draw routine
float[][] val = new float[resX][resY];

GSCapture cam;
MultiMarker nya;
float[] scaler = new float[numMarkers];
float[] noiseScale = new float[numMarkers];
float[] mountainHeight = new float[numMarkers];
float[] mountainGrowth = new float[numMarkers];

void setup() {
  size(widthCapture, heightCapture, OPENGL); // the sketch will resize correctly, so for example setting it to 1920 x 1080 will work as well
  cam = new GSCapture(this, widthCapture, heightCapture); // initializing the webcam capture at a specific resolution (correct/possible settings depends on YOUR webcam)
  //cam = new GSCapture(this, widthCapture, heightCapture,fpsCapture, »v4l2src », »/dev/video1″); // Initialise objet GSCapture désignant webcam

  cam.start(); // start capturing
  noStroke(); // turn off stroke for the rest of this sketch 🙂
  // create a new MultiMarker at a specific resolution (arWidth x arHeight), with the default camera calibration and coordinate system
  nya = new MultiMarker(this, arWidth, arHeight, camParaPath, NyAR4PsgConfig.CONFIG_DEFAULT);
  // set the delay after which a lost marker is no longer displayed. by default set to something higher, but here manually set to immediate.
  nya.setLostDelay(1);
  String[] patterns = loadPatternFilenames(patternPath);
  // for the selected number of markers, add the marker for detection
  // create an individual scale, noiseScale and maximum mountainHeight for that marker (= mountain)
  for (int i=0; i<numMarkers; i++) {
    // nya.addARMarker(patternPath + « / » + patterns[i], 80);
    scaler[i] = random(0.8, 1.9); // scaled a little smaller or bigger
    noiseScale[i] = random(0.02, 0.075); // the perlin noise scale to make it look nicely mountainy
    mountainHeight[i] = random(75, 150); // the maximum height of a mountain
  }

          // nya.addARMarker(patternPath + « / » + patterns[40], 80); // ajoute le fichier de description à l’objet principal de détection AR
        //nameMarkers[0]= patterns[40]; // mémorise le nom du marker [i]
        nameMarkers[0]= « 4x4_99.patt »; // mémorise le nom du fichier du marker voulu
        nya.addARMarker(patternPath + « / » + nameMarkers[0], 80); // ajoute le fichier de description à l’objet principal de détection AR
        println (« Fichier chargé : «  + nameMarkers[0]);

        //nya.addARMarker(patternPath + « / » + patterns[83], 80); // ajoute le fichier de description à l’objet principal de détection AR
        //nameMarkers[1]= patterns[83]; // mémorise le nom du marker [i]
        nameMarkers[1]= « 4x4_50.patt »; // mémorise le nom du fichier du marker voulu
        nya.addARMarker(patternPath + « / » + nameMarkers[1], 80); // ajoute le fichier de description à l’objet principal de détection AR
        println (« Fichier chargé : «  + nameMarkers[1]);

        //nya.addARMarker(patternPath + « / » + patterns[99], 80); // ajoute le fichier de description à l’objet principal de détection AR
        //nameMarkers[2]= patterns[99]; // mémorise le nom du marker [i]
        nameMarkers[2]= « 4x4_83.patt »; // mémorise le nom du fichier du marker voulu
        nya.addARMarker(patternPath + « / » + nameMarkers[2], 80); // ajoute le fichier de description à l’objet principal de détection AR
        println (« Fichier chargé : «  + nameMarkers[2]);

}

void draw() {
  // if there is a cam image coming in…
  if (cam.available()) {
    cam.read(); // read the cam image
    background(0); // a background call is needed for correct display of the marker results
    image(cam, 0, 0, width, height); // display the image at the width and height of the sketch window
    // create a copy of the cam image at the resolution of the AR detection (otherwise nya.detect will throw an assertion error!)
    PImage cSmall = cam.get();
    cSmall.resize(arWidth, arHeight);
    nya.detect(cSmall); // detect markers in the image
    drawMountains(); // draw dynamically flowing mountains on the detected markers (3D)
  }
}

// this function draws correctly placed 3D ‘mountains’ on top of detected markers
// while the mountains are displayed they grow (up to a certain point), while not displayed they return to the zero-state
void drawMountains() {
  // set the AR perspective uniformly, this general point-of-view is the same for all markers
  nya.setARPerspective();
  // turn on some general lights (without lights it also looks pretty cool, try commenting it out!)
  lights();
  // for all the markers…
  for (int i=0; i<numMarkers; i++) {
    // if the marker does NOT exist (the ! exlamation mark negates it)…
    if ((!nya.isExistMarker(i))) {
      // if the mountainGrowth is higher than zero, decrease by 0.05 (return to the zero-state), then continue to the next marker
      if (mountainGrowth[i] > 0) { mountainGrowth[i] -= 0.05; }
      continue;
    }
    // the following code is only reached and run if the marker DOES EXIST
    // if the mountainGrowth is lower than 1, increase by 0.03
    if (mountainGrowth[i] < 1) { mountainGrowth[i] += 0.03; }
    // the double for loop below sets the values in the 2 dimensional float array for this mountain, based on it’s noiseScale, mountainHeight and index (i).
    float xoff = 0.0;
    for (int x=0; x<resX; x++) {
      xoff += noiseScale[i];
      float yoff = 0;
      for (int y=0; y<resY; y++) {
        yoff += noiseScale[i];
        val[x][y] = noise(i*10+xoff+frameCount*0.05, yoff) * mountainHeight[i]; // this sets the value
        float distance = dist(x, y, resX/2, resY/2);
        distance = map(distance, 0, resX/2, 1, 0);
        if (distance < 0) { distance = distance; } // this line causing the four corners to flap upwards (try commenting it out or setting it to zero)
        val[x][y] *= distance; // in the default case this makes the value approach zero towards the outer ends (try commenting it out to see the difference)
      }
    }

    // get the Matrix for this marker and use it (through setMatrix)
    setMatrix(nya.getMarkerMatrix(i));
    scale(1, 1); // turn things upside down to work intuitively for Processing users
    scale(scaler[i]); // scale the mountain by it’s individual scaler
    translate(resX/2, resY/2); // translate to center the mountain on the marker
    // for the full resolution…
    for (int x=0; x<resX1; x++) {
      for (int y=0; y<resY1; y++) {
        // each face is a Shape with a fill color, together they make a colored mountain
        fill(x*20+y*20, 255x*5, y*5);
        beginShape();
        vertex(x, y, val[x][y] * mountainGrowth[i]);
        vertex((x+1), y, val[x+1][y] * mountainGrowth[i]);
        vertex((x+1), (y+1), val[x+1][y+1] * mountainGrowth[i]);
        vertex(x, (y+1), val[x][y+1] * mountainGrowth[i]);
        endShape(CLOSE);
      }
    }
  }
  // reset to the default perspective
  perspective();
}

// this function loads .patt filenames into a list of Strings based on a full path to a directory (relies on java.io)
String[] loadPatternFilenames(String path) {
  File folder = new File(path);
  FilenameFilter pattFilter = new FilenameFilter() {
    public boolean accept(File dir, String name) {
      return name.toLowerCase().endsWith(« .patt »);
    }
  };
  return folder.list(pattFilter);
}
 

Noter cet article

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Archive Mon Club Elec

Articles populaires

Newsletter

Inscrivez-vous maintenant et bénéficiez d'un soutien continu pour réaliser vos travaux électriques en toute sécurité.