Outils pour utilisateurs

Outils du site


wiki:projets:vision_de_l_abeille

F

Vision de l'abeille

Porteurs du projet :

  • Noémie Marie
  • Edène Rocheron
  • Hiba Slimani
  • Mayura Subramaniam
  • Date de début : Février 2019
  • Les objectifs de ce projet : Le but est de créer une “prothèse” permettant d'expérimenter la vision de l'abeille.
  • Date de fin : 09 Mai 2019

Notre Projet

Le but de ce projet est de faire vivre à un humain l’expérience sensoriel d'un animal. Nous avons choisis l'abeille pour sa vision particulière, en effet elle a une vision dichromatique, plus lente que la notre, avec une perception visuel très faible bien que très sensible à la lumière. De plus, sa petite taille et sa capacité à voler en font un sujet immersif et insolite.

Pour faire vivre une vrais expérience visuelle inédite à nos utilisateurs, nous allons réaliser une lunette type réalité virtuelle afin de projeter sur l’écran de l'utilisateur une simulation live de la vision de l'abeille. En effet une camera va filmer l'environnement autour de l'utilisateur de notre projet qui va directement retranscrire les caractéristique de la vision de l'abeille soit : un monde dépourvue de rouge, plus lent, avec une vision quadriller et floue.

Recherches documentaires sur l'abeille

Les yeux composés sont constitués de récepteurs sensibles à la lumière que l'on appelle ommatidies. Chaque ommatidie est orientée dans une direction différente et capte la lumière. L'abeille peut reconstituer une image selon les informations qu'elle reçoit de chaque ommatidie. Ce sont les yeux composés qui captent la couleur. D'ailleurs, l'abeille n'a pas le même spectre de vision que nous : elle ne distingue pas les rouges, mais peut voir dans l'UV (ce qui lui permet de détecter des motifs particuliers sur les fleurs, qui ont pour but d'attirer les pollinisateurs justement). De plus, l'abeille distingue mal les formes (vision “pixellisée”).

Les ocelles, au nombre de trois, sont situés sur la face frontale de l'abeille. Ils sont très sensibles à la lumière, et permettent de détecter les changements de luminosité. Ils aident à la stabilité en vol, en détectant s'il y a un obstacle au-dessus de l'abeille (détection d'une ombre, faible luminosité) ou s'il n'y a rien (pas d'obstacle donc forte luminosité, lumière du soleil). Ils peuvent aussi permettre à l'abeille de détecter le moment de la journée (jour, nuit).

Ce sont les fonctions de ces deux organes que nous allons tenter de reproduire via une “prothèse”.

Avancement du projet

Idée

Notre première idée consistait à créer une sorte de casque de réalité virtuelle avec une fente pour insérer le smartphone. On pourrait ainsi expérimenter la vision de l'abeille selon différentes possibilités :

  • Avoir une vidéo toute prête, modifiée selon les particularités de la vision des abeilles (mais pas assez immersif)
  • Modéliser un environnement 3D où on pourrait diriger l'abeille et voir ce qu'elle observe (mais trop compliqué)
  • Proposer un “live” : le smartphone affiche ce que la personne voit (via une caméra au niveau de la tête), mais la vidéo est modifiée sur ordinateur à l'aide de Processing et Arduino, avant d'être retransmise sur le smartphone.

Nous avons retenu cette dernière possibilité.

Prototype : Réalisation d'un casque

Nous voudrions réaliser un casque dans lequel on pourrait insérer le smartphone au niveau d'une fente devant les yeux, la webcam qui filmerait l'environnement devant la personne, ainsi que les capteurs Sonar / photorésistances qui joueraient le rôle des ocelles (capteurs de luminosité).

Le casque nous permettrai d’intégrer tout les capteur dans un mémé dispositif avec la webcam intégré dans le casque et les capteurs lumineux fixés sur le dessus.

Impossible de le réaliser à l'imprimante 3D car cela serai beaucoup trop long et trop coûteux en matériel. Nous avons donc créé un moule en papier mâché, carton, et avec un ballon, afin de créer une forme ronde par thermoformage plastique qui serai notre haut du casque. Nous avons fait 3 tests : deux tests avec le moule en papier mâché, et un test avec un dôme en polystyrène.

Moule en papier mâché :

Forme thermo-formé avec la boule de polystyrène :

Les défauts du moule en papier mâchés sont très visible et notre forme n'est pas du tout lisse, avec beaucoup d'imperfection. Ce résultat de nous satisfait pas, nous essayons donc de lisser le dessus avec de la patte fimo. Pour les contours la patte marche assez bien, mais pour le dessus cela ne fait que venir pas dessus les défauts sans les masqués.

La boule en polystyrène est quant à elle très lisse, mais trop petite pour notre casque. Nous ne pouvons donc pas l'utiliser.

Prototype : la lunette

Pour cela nous réalisons un patron avec Inkscape pour pouvoir les découper à la découpeuse laser puis assembler les pièces de celle-ci. Nous utilisons des planches de medium de 3mm pour que la lunette soit la plus légère possible.

Le fablab ne dispose pas de planche de 3mm entière, nous utilisons donc des chutes pour nos 1er découpes. Or nos plus grandes pièces de rentre dans aucune planche, nous prenons donc en 1er test une planche de 5mm assez grande pour accueillir nos découpes.

Les découpes terminer nous assemblons nos pièces. Or la grande forme du dessus ne s’emboîte pas avec le reste, de plus nous nous rendons conte que l’emboîtement des pièces diminue l'espace de notre lunette qui par conséquent devient trop petite. De plus nous n'avions pas pris assez de recule par rapport à la longueur de la lunette et nous devons l'allonger afin d'avoir une meilleur vue sur l'écran du téléphone. De plus nous travaillions pour que la pièce intérieur que nous avions initialement prévu de coller dans la lunette s'encoche dans notre lunette, nous tentons donc de réaliser une gravure pour que celle-ci puisse s’emboîter dans la lunette.

Nous corrigeons les dimensions et le problème d'encochement sur ce 2em patron revisité.

Nous trouvons finalement des planches qui nous correspondent, et imprimons notre model à partir des schéma corrigés. La lunette est bancale mais globalement tout s’emboîte assez bien avec quelques retouche de découpe. Nous collons tout à la colle à bois afin d’être sur que celle-ci tienne bien. Notre model de lunette est prêt.

Pour finaliser la partie lunette, nous la peignons en noir afin que celle-ci soit moderne et discrète et ajoutons des lanières sur les coté avec un clip afin de pouvoir l'enfiler sur la tête et de pouvoir régler la circonférence.

PHOTO LUNETTE 1 ET 2:

Lors de l'essaie de la lunette nous remarquons que les contours blesse assez le visage, surtout quand on serre fort la lanière. On pose alors des mousses sur les cotés haut et bas afin d'accentuer le confort. Après cela la lunette est plutôt agréable à porter. C'est la forme final de la lunette.

PHOTO LUNETTE MOUSSE:

Assemblage du Prototype

La lunette est donc à son étape final mais pas notre prototype.

La lunette n'en est que la 1er partie.

Nous avion l'idée de relier la lunette a un casque thermo-former afin de crée notre dispositif, mais celui-ci n'est pas fonctionnel.

Nous nous retournons donc vers une casquette afin d'en faire notre support au niveau de la tête, celle-ci ayant l'avantage d’être légère et réglable pour s'adapter à un maximum de personnes.

Nous décousons son écusson et coupons sa visière afin de s'approcher le plus possible d'un casque et la peignons en noir pour la fondre avec notre lunette. Nous accrochons d’ailleurs la partie avant de la casquette à la partie frontal de la lunette : on a donc un 1er morceau fonctionnel avec la lunette qui tiens en place, renforcé par la force de la casquette.

Le but est par la suite de relier l'avant de la lunette à notre casquette afin d’alléger le poids sur l'avant ou ce trouvera notre téléphone, en créant un effet balancier.

Pour cela nous venons coller sur l'avant de notre lunette une plaque en plastique flexible peint à la bombe en argenté pour un coté moins uniforme et ajouter un effet métallique. Nous relions celle-ci à la casquette en la collant sur la face avant. Nous découpons des sortes de languettes sur notre plaque de plastique afin d'avoir une meilleur surface d'accrochage sur la casquette en tissus. Nous découpons également un trous dans notre panneau de plastique juste au dessus de la lunette afin de pouvoir y glisser la camera de façon la plus discrète et fondu possible.

Avant ces lamelles nous créons un emplacement rond qui va venir accueillir notre Arduino avec nos capteurs lumineux caché sous la boule que nous avons thermo-former à partir de la sphère en polystyrène. Nous peignons celle-ci en noir, et perçons 3 trous sur le dessus afin de laisser sortir nos capteurs lumineux en gardant l'Arduino caché. Nous viendrons coller la sphère avec de la colle à chauffer afin de régulariser les bords de la sphère qui à été très difficile à découper droit.

Prototype Final

Une fois notre planche relier à la lunette puis à la casquette le dispositif est terminé.

Pour un soucis de transport nous décidons d'assembler les pièces finales dans la salle le jour de la démonstration du prototype afin qu'aucun matériaux ne puisse s'arracher, s’abîmer, ce rayer ou ce tordre. Tout est donc prêt à être assembler:

Pour projeter l’écran de notre pc sur le téléphone qui ce trouve dans le dispositif nous utilisions l'application de diffusion ApowerMiror, lors de la représentation en cours nous utilisions le wifi de l'UPMC pour diffuser, l’image était plutôt saccadée et certaines images restaient figées a cause de la mauvaise connexion. En passant en 4G l'image était beaucoup plus fluide et de n’interrompait pas.

J'ai pu faire le tour de la salle avec le dispositif sur moi, en ne regardant que l’écran dans le casque. J'ai pu éviter tous les objets sans problème et mémé passer dans des passages étroits.

Le défaut majeur lié à l'image est la taille de la fenêtre de diffusion, en effet la résolution maximale de la caméra ne nous permet pas d'avoir une image plus grande que 800*600 pxl, nous n'avons donc pas une diffusion en pleine écran sur notre téléphone.

zupimages.net_up_19_21_xxho.jpg zupimages.net_up_19_21_1evh.jpg

Partie Sensoriel :

Retranscription de la perception visuelle des abeilles

Retranscription de la perception par les ommatidies des yeux composés :

  • Filtre qui supprime la couleur rouge, car les abeilles ne perçoivent pas cette couleur (Processing + webcam)
  • Filtre qui “pixellise” l'image, car l'abeille a une vision des formes limitée (Processing + webcam)

Retranscription de la perception par les ocelles :

  • 1er essai : photorésistances qui permettent de détecter le changement de luminosité (Arduino), couplé à un filtre pour assombrir l'image si on détecte une forme ou un mouvement au dessus du récepteur (Processing). Problème rencontré : la portée est trop faible.
  • 2ème essai : capteur Sonar

Programmes

Photorésistances (Arduino et Processing) : ocelles

Nous voulions donc mimer la fonction des ocelles (détecter les changements de luminosité) en utilisant des photorésistances. Pour cela nous avons repris le principe du SensorShield disponible sur le github. Nous voulions associer le changement de luminosité détecté par la photorésistance sur Arduino, à un assombrissement de l'image sur la vidéo à l'aide de Processing.

zupimages.net_up_19_16_5iyk.jpg zupimages.net_up_19_16_il8j.jpg zupimages.net_up_19_16_lmrt.jpg

  #include <sensorShieldLib.h>
  SensorShield board;
  //DECLARE SENSOR'S AND OTHER PINS 
  int lightPin = A0;  // LDR pin
  int ledPin = 11;    // led pin
  int lightPin1 = A1;  // LDR pin
  int ledPin1 = 10;    // led pin
  int lightPin2 = A2;  // LDR pin
  int ledPin2 = 9;    // led pin
  //VARIABLES FOR THE OUTPUTS 
  //LED variables
  int lightLevel;
  int mappedLightLevel;
  int lightLevel2;
  int mappedLightLevel2;
  int lightLevel3;
  int mappedLightLevel3;
  void setup() {
    initialises and start Serial with 9600 baudrate
    board.init();
    add analog sensors to sensorShield
    board.addSensor("capteurLDR1", A0);
    board.addSensor("capteurLDR2", A1);
    board.addSensor("capteurLDR3", A2);
    LED display
    pinMode(ledPin, OUTPUT);
  }
  void loop() {
    /*read the value, if there are changes update it and send it through serial*/
    board.update();
    // turn on the led on the shield with LDR input values
    lightLevel = analogRead(lightPin);
    mappedLightLevel = map(lightLevel, 113, 600, 0, 255);
    analogWrite(ledPin, mappedLightLevel);
    
     lightLevel2 = analogRead(lightPin2);
    mappedLightLevel2 = map(lightLevel2, 113, 600, 0, 255);
    analogWrite(ledPin2, mappedLightLevel2);
    
     lightLevel3 = analogRead(lightPin3);
    mappedLightLevel3 = map(lightLevel3, 113, 600, 0, 255);
    analogWrite(ledPin3, mappedLightLevel3);
  }

Donc on a utilise 3 capteurs de lumière pour imiter les 3 yeux au dessus de la tête de l'abeille(leur fonction principal est de permettre l'abeille a se positionner dans l'espace).

  • * L'ARDUINO FINI: ====Webcam et filtres (Processing) : ommatidies==== Grâce à Processing, on peut appliquer des filtres sur l'image filmée par la caméra pour enlever les couleurs rouges, et pour pixelliser l'image. Dans un premier temps, nous avons commencé par utiliser un filtre sur une image avant de l'appliquer à une caméra. Première version du code : pImage = img; void setup() { size(200, 200); img = loadImage(“sunflower.jpg”); } void draw() { loadPixels(); We must also call loadPixels() on the PImage since we are going to read its pixels. img.loadPixels(); for (int y = 0; y < height; y++ ) { for (int x = 0; x < width; x++ ) { int loc = x + y*width; The functions red(), green(), and blue() pull out the three color components from a pixel. float r = red(img.pixels [loc]); float g = green(img.pixels[loc]); float b = blue(img.pixels[loc]); Image Processing would go here If we were to change the RGB values, we would do it here, before setting the pixel in the display window. Set the display pixel to the image pixel pixels[loc] = color(r, g*10, b*10); } } updatePixels(); } Résultat du programme : zupimages.net_up_19_16_mo0r.jpg Deuxième version : Nous avons utilisé un autre programme processing avec une caméra extérieure. import processing.video.*; Capture video; boolean cheatScreen; void setup() { size(640, 480); String[] cameras = Capture.list(); if (cameras.length == 0) { println(“There are no cameras available for capture.”); exit(); } else { println(“Available cameras:”); for (int i = 0; i < cameras.length; i++) { println(cameras[i]); } The camera can be initialized directly using an element from the array returned by list(): video = new Capture(this, cameras[0]); video.start(); } /* This the default video input, see the GettingStartedCapture example if it creates an error video = new Capture(this, 640, 480); Start capturing the images from the camera video.start(); */ } void captureEvent(Capture c) { c.read(); } void draw() { background(0); int index = 0; video.loadPixels(); for (int y = 1; y < video.height; y++) { for (int x = 0; x < video.width; x++) { int pixelColor = video.pixels[index]; Faster method of calculating r, g, b than red(), green(), blue() int r = (pixelColor » 16) & 0xff; int g = (pixelColor » 8) & 0xff; int b = pixelColor & 0xff; Move to the next pixel index++; int res = 4; 30; if (x % res == 0 && y % res == 0) { Move over for next character r = 0; g = g; b = b; color couleur = color(r, g, b); set(x, y, couleur); fill(couleur); noStroke(); rect(x, y, 50/ 2, 50/ 2); } } } if (cheatScreen) { image(video, 0, height - video.height); set() is faster than image() when drawing untransformed images set(0, height - video.height, video); } } /
    • Handle key presses:
    • 'c' toggles the cheat screen that shows the original image in the corner
    • 'g' grabs an image and saves the frame to a tiff image
      • /

void keyPressed() {

        switch (key) {
        case 'g': 
          saveFrame(); 
          break;
        case 'c': 
          cheatScreen = !cheatScreen; 
          break;
    }
  }

Résultats du programme, avec comparaison :

On ne voit pas le rouge, et la vision est pixellisée, mais il manque le motif hexagonal.Pour trouver la taille parfaite pour répliquer l'image que les abeilles voient on a utilise des fonctions différentes de Processing.

Troisième version (La version finale):

  import processing.video.*;
  Capture video;
  boolean cheatScreen;
  void setup() {
    size(640, 480);
    String[] cameras = Capture.list();
    if (cameras.length == 0) {
      println("There are no cameras available for capture.");
      exit();
    } else {
      println("Available cameras:");
      for (int i = 0; i < cameras.length; i++) {
        println(cameras[i]);
      }
      
      // The camera can be initialized directly using an 
     // element from the array returned by list():
      video = new Capture(this, cameras[0]);
      video.start();
      drawHex(400, 400, 44);
    }
    /*
     // This the default video input, see the GettingStartedCapture 
     // example if it creates an error
     video = new Capture(this, 640, 480);
 
     // Start capturing the images from the camera
     video.start();
 
     */ 
  }
  void captureEvent(Capture c) {
    c.read();
  }
  void draw() {
    background(0);
    int index = 0;
    video.loadPixels();
    for (int y = 1; y < video.height; y++) {
      for (int x = 0; x < video.width; x++) {
        int pixelColor = video.pixels[index];
        // Faster method of calculating r, g, b than red(), green(), blue() 
        int r = (pixelColor >> 16) & 0xff;
        int g = pixelColor & 0xff;
        int b = pixelColor & 0xff;
        // Move to the next pixel
        index++;
        int res = 14;
        if (x % res == 0 && y % res == 0) {
      r = 3;
      g = g;
      b = b;
          color couleur = color(r, g, b);
          set(x, y, couleur);
          fill(couleur);
          noStroke();
         
          drawHex(x, y, 6.64);
        }
      }
    }

   // println("----");
   // println(map(mouseY, 0, height, 1, 100));
  //println(map(mouseX, 0, width, 0, 50));
    if (cheatScreen) {
      //image(video, 0, height - video.height);
      // set() is faster than image() when drawing untransformed images
      set(0, height - video.height, video);
    } 
   }
   void drawHex(float x, float y, float gs) {
    beginShape();
    for(int i=0;i<6;i++){
      float angle = i * 2 * PI / 6;
      vertex(x + gs*cos(angle),y + gs*sin(angle));
    }
    endShape(CLOSE);
  }
  /**
   * Handle key presses:
   * 'c' toggles the cheat screen that shows the original image in the corner
   * 'g' grabs an image and saves the frame to a tiff image
   */
   void keyPressed() {
     switch (key) {
     case 'g': 
     saveFrame(); 
     break;
     case 'c': 
       cheatScreen = !cheatScreen; 
      break;
    }
  }

Pour se connecter à la webcam extérieure :

  video = new Capture(this, "name=aGent V6 HD,size=640x480,fps=15");

Résultats du programme :

Après pour arriver a faire une connexion entre Processing et Arduino on a utilise le code en bas:

 
 
  import vsync.*;
  /* 
   * sensoShield n1
   * SensorShieldlib Lionel Radisson -Makio135
   * https://github.com/MAKIO135/sensorShieldLib
   */
  
  import processing.serial.*;
  ////// SENSORSHIELD //////  
  Serial myPort;
  JSONObject json;
  ////// VARIABLES CAPTEURS INPUT //////
  float lightValue1, lightValue2, lightValue3;// LDR light
  ////// VARIABLES OUTPUT //////
  float mappedLightValue1,mappedLightValue2,mappedLightValue3;
  void setup() {
    String serialName = "COM3";
    size( displayWidth, displayHeight);
    printArray( Serial.list() );
    myPort = new Serial(this, serialName, 9600); // indicate your arduino port
    myPort.clear();
  }
  void draw() {
    // read sensorShield
    while ( myPort.available() > 0 ) {
      String data = myPort.readStringUntil( '\n' );
      if ( data != null ) {
        println( data ); 
        try {
          json = JSONObject.parse( data );
          // get the values of your sensors from serial (arduino)
          lightValue1 = json.getInt("capteurLDR1");
          lightValue2 = json.getInt("capteurLDR2");
          lightValue3 = json.getInt("capteurLDR3");
        } 
        catch ( Exception e ) {
          e.printStackTrace();
        }
        dataVis();
      }
    }
  void keyPressed(){ 
  
    switch(key):
        case 'c':
        noLoop();
          break;
      }
  }

Matériel et logiciels utilisés

  • *Logiciels : Arduino, Processing, (Fritzing) Matériel** :
  • Webcam
  • Ordinateur pour le traitement des données par Processing et Arduino
  • Smartphone à insérer dans le casque / lunettes VR
  • Capteur Sonar / photorésistances avec Arduino
  • Résistances
  • Application pour faire apparaître l’écran de l'ordi sur le smartphone(aPowerMirror)
wiki/projets/vision_de_l_abeille.txt · Dernière modification: 2020/10/05 16:39 (modification externe)