Difference between revisions of "Visual navigation for Acrob or SBOT robot with Android with camera ( Marek Kádek, Jana Sucháneková)"

From RoboWiki
Jump to: navigation, search
(Trénovanie neurónovej siete)
(Ukážka projektu)
 
(10 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
== Úvod ==
 
== Úvod ==
  
Cieľom projektu Editing Visual navigation for Acrob with Android with camera bolo vytvoriť robota, reagujúceho na vizuálne podnety v labyrinte pomocou snímania okolia kamerou mobilu s operačným systémom Android. Robot má byť spojený s telefónom pomocou protokolu bluetooth.
+
Cieľom projektu '''Editing Visual navigation for Acrob with Android with camera''' bolo vytvoriť robota, reagujúceho na vizuálne podnety v labyrinte pomocou snímania okolia kamerou mobilu s operačným systémom Android. Robot má byť spojený s telefónom pomocou protokolu bluetooth.
  
 
Výzor robota:
 
Výzor robota:
Line 172: Line 172:
  
 
=== Neurónová sieť ===
 
=== Neurónová sieť ===
Na tvorbu neurónovej siete sme použili knižnicu [http://neuroph.sourceforge.net/ Neuroph]. Tam sme natrénovali, aby rozoznávala požadované tvary. Stretli sme sa s nasledovnými problémami:
+
 
# Najnovšie Neuroph štúdio beží pod Java 1.7, a využíva novšie funkcie knižnice. Po natrénovaní sme sa snažili načítať natrénovanú sieť na Androide, avšak neúspešne.
+
''Na tvorbu neurónovej siete sme použili knižnicu [http://neuroph.sourceforge.net/ Neuroph]. Tam sme natrénovali, aby rozoznávala požadované tvary. Stretli sme sa s nasledovnými problémami:
# Staršia verzia Neuroph štúdia má problém s ukladaním siete. Tento problém sme dlho hľadali a zistili sme, že sa jedná o bug aplikácie, ukladanie funguje iba veľmi zriedka (spočiatku uloží nenatrénovanú sieť, no natrénovanú neukladá).
+
 
# Sieť sa v androide musí načítať vo zvláštnom vlákne, aby sme mohli využiť väčšiu stack size:
+
''# Najnovšie Neuroph štúdio beží pod Java 1.7, a využíva novšie funkcie knižnice. Po natrénovaní sme sa snažili načítať natrénovanú sieť na Androide, avšak neúspešne.
 +
 
 +
''# Staršia verzia Neuroph štúdia má problém s ukladaním siete. Tento problém sme dlho hľadali a zistili sme, že sa jedná o bug aplikácie, ukladanie funguje iba veľmi zriedka (spočiatku uloží nenatrénovanú sieť, no natrénovanú neukladá).''
 +
 
 +
''# Sieť sa v androide musí načítať vo zvláštnom vlákne, aby sme mohli využiť väčšiu stack size:''''''
 
     ...
 
     ...
 
     new Thread(null, loadDataRunnable, "dataLoader", 65536).start();
 
     new Thread(null, loadDataRunnable, "dataLoader", 65536).start();
Line 187: Line 191:
 
         }
 
         }
 
     };
 
     };
 +
 +
'''Neuroph štúdio sme nakoniec nahradili vlastným programom.'''
  
 
Príklad tvarov:
 
Príklad tvarov:
Line 195: Line 201:
 
==== Trénovanie neurónovej siete ====
 
==== Trénovanie neurónovej siete ====
  
Ukážka spôsobu implementácie trénovania neurónovej siete:
+
Po neúspešnom trápení sa s Neuroph štúdiom pri trénovaní robota v rozpoznávaní tvarov sme sa rozhodli zahodiť celý Neuroph projekt a napísať si vlastný kód na trénovanie neurónovej siete.
 +
 
 +
Postup pri trénovaní:
 +
# nafotili sme fotografie (každý tvar, vrátane null - prázneho papiera, z viacerých uhlov, vzdialeností a za rôznych svetelných podmienok)
 +
# fotky sme poslali ako vstup do programu
 +
# výstup sa zisťoval podľa názvu fotky (circle, square, null) a podľa toho sa sieť natrénovala
 +
 
 +
Ukážka implementácie trénovania neurónovej siete:
  
 
     import java.awt.image.BufferedImage;
 
     import java.awt.image.BufferedImage;
 
     import java.awt.image.Raster;
 
     import java.awt.image.Raster;
 
     import java.io.File;
 
     import java.io.File;
 +
    import java.io.IOException;
 
     import java.util.ArrayList;
 
     import java.util.ArrayList;
 
     import javax.imageio.ImageIO;
 
     import javax.imageio.ImageIO;
 +
    import org.neuroph.contrib.imgrec.ImageRecognitionPlugin;
 +
    import org.neuroph.contrib.imgrec.ImageRecognitionSample;
 +
    import org.neuroph.contrib.imgrec.image.Dimension;
 +
    import org.neuroph.core.NeuralNetwork;
 
     import org.neuroph.core.learning.SupervisedTrainingElement;
 
     import org.neuroph.core.learning.SupervisedTrainingElement;
 
     import org.neuroph.core.learning.TrainingSet;
 
     import org.neuroph.core.learning.TrainingSet;
Line 209: Line 227:
 
         public static final int INPUT_VECTOR_SIZE = 20*20*3;
 
         public static final int INPUT_VECTOR_SIZE = 20*20*3;
 
         public static final int OUTPUT_VECTOR_SIZE = 3;
 
         public static final int OUTPUT_VECTOR_SIZE = 3;
         public static void main(String[] args) {
+
         public static void testNeural() {
             ArrayList<File> images = listFilesForFolder(new File("./imgs/"));
+
             NeuralNetwork nn = NeuralNetwork.load("networks/latest.nnet");
             TrainingSet<SupervisedTrainingElement> trainings = new TrainingSet<SupervisedTrainingElement>(INPUT_VECTOR_SIZE, OUTPUT_VECTOR_SIZE);
+
            nn.setInput(getTrainingSet((new File("imgs/sqsq.png"))).getInput());
             for (File f :images) {
+
            nn.calculate();
                 addFileToTraining(f, trainings);
+
             double[] output = nn.getOutput();
 +
             for (double dd : output) {
 +
                 System.out.println(dd);
 
             }
 
             }
             MultiLayerPerceptron mlp = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, INPUT_VECTOR_SIZE,  24, 12, OUTPUT_VECTOR_SIZE);
+
    }
            System.out.println("training");
+
    public static void main(String[] args) {
            mlp.learn(trainings);
+
        ArrayList<File> images = listFilesForFolder(new File("./imgs/"));
            mlp.save("./networks/latest.nnet");
+
        TrainingSet<SupervisedTrainingElement> trainings = new TrainingSet<SupervisedTrainingElement>(INPUT_VECTOR_SIZE, OUTPUT_VECTOR_SIZE);
            System.out.println("done");
+
        for (File f :images) {
        } //output
+
             trainings.addElement(getTrainingSet(f));
        public static void addFileToTraining(File file, TrainingSet<SupervisedTrainingElement> trainings) {
+
        }
            ArrayList<Double> input = new ArrayList<>();
+
        MultiLayerPerceptron mlp = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, INPUT_VECTOR_SIZE,  24, 12, OUTPUT_VECTOR_SIZE);  
            ArrayList<Double> output = new ArrayList<>();
+
        System.out.println("training");
            if (file.getName().startsWith("circle")) {
+
        mlp.learn(trainings);
                output.add(1.0d);
+
        mlp.save("./networks/latest.nnet");
                output.add(0.0d);
+
        System.out.println("done");
                output.add(0.0d);
+
    }
                System.out.println("Found circle: " + file.getName());
+
    public static SupervisedTrainingElement getTrainingSet(File file) {
            } else if (file.getName().startsWith("other")) {
+
        ArrayList<Double> input = null;
                output.add(0.0d);
+
        ArrayList<Double> output = new ArrayList<>();
                output.add(1.0d);
+
        //output
                output.add(0.0d);
+
        if (file.getName().startsWith("circle")) {
                System.out.println("Found other: " + file.getName());
+
            output.add(1.0d);
            } else if (file.getName().startsWith("square")) {
+
            output.add(0.0d);
                output.add(0.0d);
+
            output.add(0.0d);
                output.add(0.0d);
+
            System.out.println("Found circle: " + file.getName());
                output.add(1.0d);
+
        } else if (file.getName().startsWith("other")) {
                System.out.println("Found square: " + file.getName());
+
            output.add(0.0d);
            } // input
+
            output.add(1.0d);
             try {
+
            output.add(0.0d);
                final BufferedImage bf = ImageIO.read(file);
+
            System.out.println("Found other: " + file.getName());
                final Raster raster = bf.getData();
+
        } else if (file.getName().startsWith("square")) {
                for (int i = 0 ; i < raster.getHeight(); i++) {
+
            output.add(0.0d);
                    for (int j = 0; j < raster.getWidth(); j++) {
+
            output.add(0.0d);
                        double[] buff = new double[3];
+
            output.add(1.0d);
                        raster.getPixel(i, j, buff);
+
            System.out.println("Found square: " + file.getName());
                        input.add(buff[0] / 255.0d);
+
        }  
                        input.add(buff[1] / 255.0d);
+
        // input
                        input.add(buff[2] / 255.0d);
+
        try {
                    }
+
             input = getInput(file);
                }
+
        } catch (Exception e ) {
            } catch (Exception e ) {
+
            e.printStackTrace();
                e.printStackTrace();
+
        }
 +
    return new SupervisedTrainingElement(input, output);
 +
    }
 +
    public static ArrayList<Double> getInput(File file) throws IOException {
 +
        ArrayList<Double> input = new ArrayList<>();
 +
        final BufferedImage bf = ImageIO.read(file);
 +
        final Raster raster = bf.getData();
 +
        for (int i = 0 ; i < raster.getHeight(); i++) {
 +
            for (int j = 0; j < raster.getWidth(); j++) {
 +
                double[] buff = new double[3];
 +
                raster.getPixel(i, j, buff);
 +
                input.add(buff[0] / 255.0d);
 +
                input.add(buff[1] / 255.0d);
 +
                input.add(buff[2] / 255.0d);
 
             }
 
             }
        trainings.addElement(new SupervisedTrainingElement(input, output));
 
 
         }
 
         }
 +
        return input;
 +
    }
 
     public static ArrayList<File> listFilesForFolder(final File folder) {
 
     public static ArrayList<File> listFilesForFolder(final File folder) {
 
         ArrayList<File> files = new ArrayList<File>();
 
         ArrayList<File> files = new ArrayList<File>();
Line 262: Line 296:
 
             if (fileEntry.isDirectory()) {
 
             if (fileEntry.isDirectory()) {
 
             } else {
 
             } else {
            files.add(fileEntry);
+
                files.add(fileEntry);
 
             }
 
             }
 
         }
 
         }
    return files;
+
        return files;
 
     }
 
     }
 
     }
 
     }
 +
 +
Výsledky trénovania sú oveľa presnejšie a lepšie ako pri využívaní Neuroph štúdia.
  
 
== Ukážka projektu ==
 
== Ukážka projektu ==
Line 273: Line 309:
 
Robot sa každých 750 ms pozrie na to, čo vidí a to vyhodnotí. Z tohto dôvodu je pohyb robota nespojitý. Obraz sa naškáluje na 20x20 pixlov.
 
Robot sa každých 750 ms pozrie na to, čo vidí a to vyhodnotí. Z tohto dôvodu je pohyb robota nespojitý. Obraz sa naškáluje na 20x20 pixlov.
  
[https://www.youtube.com/watch?feature=player_embedded&v=c8fiv6LRjeI Youtube video]
+
<youtube>VkO6h_kL9GM</youtube>
  
 
== Záver ==
 
== Záver ==
 
Robot dokáže rozoznávať medzi červeným kruhom a modrým štvorcom. Robot pri rozpoznávaní tvarov preukazuje menšie chybovosti, vyplývajúce z natrénovania neurónovej siete. Sklon kamery, pripevnenej na robotovi, spôsobuje tiež menšie odchýlky. Pohyb je nespojitý.
 
Robot dokáže rozoznávať medzi červeným kruhom a modrým štvorcom. Robot pri rozpoznávaní tvarov preukazuje menšie chybovosti, vyplývajúce z natrénovania neurónovej siete. Sklon kamery, pripevnenej na robotovi, spôsobuje tiež menšie odchýlky. Pohyb je nespojitý.
 
  
 
== Zdrojáky ==
 
== Zdrojáky ==
[[Media:src.zip]]
+
[[Media:src2.zip]]
  
 
== Zdroje ==
 
== Zdroje ==

Latest revision as of 13:36, 13 June 2013

Úvod

Cieľom projektu Editing Visual navigation for Acrob with Android with camera bolo vytvoriť robota, reagujúceho na vizuálne podnety v labyrinte pomocou snímania okolia kamerou mobilu s operačným systémom Android. Robot má byť spojený s telefónom pomocou protokolu bluetooth.

Výzor robota:

Rob.jpg

Postup riešenia

V prvej etape tvorby projektu bolo základom zložiť robota.

Ukážka obvodu:

Obvod.jpg


V druhej etape sme vytvorili bluetooth spojenie medzi robotom a mobilným telefónom, pomocou knižnice Amarino - Android meets Andruino. Z rôznych zdrojov a diskusií na internete sme sa dozvedeli, že vytvorenie spojenia z android bluetooth na bluetooth modul robota je mnohokrát problémové a chyby sú ťažko odhaliteľné. Veľa rád práve smerovalo na použitie knižnice Amarino na riešenie tohoto problému.

Postup tvorby spojenia:

  1. Android zariadenie spárujeme s bluetooth modulom.
  2. Na android zariadenie nainštalujeme Amarino.
  3. Vytvoríme projekt v eclipse a do build path pridáme knižnicu.
  4. Vytvoríme a nacvičíme neurónovú sieť

Komunikácia

Ukážka nadviazania spojenia pomocou knižnice:

   private static final String DEVICE_ADDRESS =  "00:06:66:03:73:7B";
   private ArduinoReceiver arduinoReceiver = new ArduinoReceiver();
   
   @Override
   protected void onStart() {
       super.onStart();
       registerReceiver(arduinoReceiver, new IntentFilter(AmarinoIntent.ACTION_RECEIVED));
       Amarino.connect(this, DEVICE_ADDRESS);
   }
   @Override
   protected void onStop() {
       super.onStop();
       Amarino.disconnect(this, DEVICE_ADDRESS);
       unregisterReceiver(arduinoReceiver);
   }
   public class ArduinoReceiver extends BroadcastReceiver {
       @Override
       public void onReceive(Context context, Intent intent) {
       String data = null;
       final String address = intent.getStringExtra(AmarinoIntent.EXTRA_DEVICE_ADDRESS);
       final int dataType = intent.getIntExtra(AmarinoIntent.EXTRA_DATA_TYPE, -1);
       if (dataType == AmarinoIntent.STRING_EXTRA) {
           data = intent.getStringExtra(AmarinoIntent.EXTRA_DATA);			
           if (data != null){
               try {
                   // tu mozeme spracovat data, ktore robot posle na mobil
               } 
               catch (Exception e) { 
           }
       }
    }
  }

Na odosielanie dát smerom na Arduino využívame funkciu

   Amarino.sendDataToArduino(context, address, flag, data)

v našom prípade

   Amarino.sendDataToArduino(MainActivity.this, DEVICE_ADDRESS, 'd', 5);

Na strane arduina potom pripravíme funkciu nasledovne: 1. includujeme hlavičku - #include <MeetAndroid.h> 2. v setupe nabindujeme 'd' na funkciu zatoč

   MeetAndroid meetAndroid;
   void setup()  
   {
       ...
       meetAndroid.registerFunction(zatoc, 'd');
       ...
   }

3. pripravíme si funkciu zatoc

   void zatoc(byte flag, byte numOfValues)
   {
       ...
       // kod na zatocenie
       ...
   }

4. do loopu pridáme kód na príjmanie a spracovanie správ

   void loop()  
   {
       ...
       meetAndroid.receive(); 
       ...
   }


Čítanie dát z kamery

Kód číta dáta z kamery, ktoré sú v YUV formáte, a využíva triedu YuvImage implementovanú v Androide na kompresiu do JPEG formátu. Následne ho preškáluje na požadovanú veľkosť (napr. 20x20) a uloží. Tieto dáta sú nasledne čítané a je na ne púštaná detekcia neurónovou sieťou.

   ... (rôzne inicializácie) ...
   int dataBufferSize=(int)(previewSize.height*previewSize.width*
   (ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat())/8.0));
   mCamera.addCallbackBuffer(new byte[dataBufferSize]);
   mCamera.addCallbackBuffer(new byte[dataBufferSize]);
   mCamera.addCallbackBuffer(new byte[dataBufferSize]);
   final Rect rect = new Rect(0, 0, previewSize.width, previewSize.height);
   mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
   private long timestamp=0;
   private FileOutputStream out;
   private Bitmap bmp;
   final String seeFile = MainActivity.this.getCurrentSeeFile();
   public synchronized void onPreviewFrame(byte[] data, Camera camera) {
       synchronized (MainActivity.this) {
           try {
               try {
               YuvImage image = new YuvImage(data, parameters.getPreviewFormat(), previewSize.width, previewSize.height, null);
               OutputStream outStream = null;
               try {
                   outStream = new FileOutputStream( seeFile );
                   image.compressToJpeg(rect, 100, outStream);
                   outStream.flush();
                   outStream.close();
                   bmp = BitmapFactory.decodeFile( seeFile );
                   bmp = Bitmap.createScaledBitmap(bmp, SCALE_WIDTH, SCALE_HEIGHT, false);
                   out = new FileOutputStream( seeFile );
                   bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
                   out.flush();
                   out.close();
                   } 
                   catch (FileNotFoundException e) 
                   {
                   e.printStackTrace();
                   }
                   catch (IOException e) 
                   {
                   e.printStackTrace();
                   }
    	    } catch (Exception e1) {
             e1.printStackTrace();
           }           
              camera.addCallbackBuffer(data);
          } catch (Exception e) {
              return;
           }
       return;
       }
   }
   });  
   try {
   mCamera.startPreview();
   } catch (Throwable e) {
   mCamera.release();
   mCamera = null;
   return;
   }

Kameru je potrebné na konci uzavrieť, na to slúži metóda:

   private void stopVideo() {
   if(null==mCamera)
       return;
       try {
           mCamera.stopPreview();
           mCamera.setPreviewDisplay(null);
           mCamera.setPreviewCallbackWithBuffer(null);
           mCamera.release();
       } catch (IOException e) {
           e.printStackTrace();
           return;
       }
       mCamera = null;
   }

Neurónová sieť

Na tvorbu neurónovej siete sme použili knižnicu Neuroph. Tam sme natrénovali, aby rozoznávala požadované tvary. Stretli sme sa s nasledovnými problémami:

# Najnovšie Neuroph štúdio beží pod Java 1.7, a využíva novšie funkcie knižnice. Po natrénovaní sme sa snažili načítať natrénovanú sieť na Androide, avšak neúspešne.

# Staršia verzia Neuroph štúdia má problém s ukladaním siete. Tento problém sme dlho hľadali a zistili sme, že sa jedná o bug aplikácie, ukladanie funguje iba veľmi zriedka (spočiatku uloží nenatrénovanú sieť, no natrénovanú neukladá).

# Sieť sa v androide musí načítať vo zvláštnom vlákne, aby sme mohli využiť väčšiu stack size:'

   ...
   new Thread(null, loadDataRunnable, "dataLoader", 65536).start();
   ...
   private Runnable loadDataRunnable = new Runnable() {
       public void run() {
           nnet = NeuralNetwork.load(  getResources().openRawResource(NETWORK_ID)  );
           imageRecognition = (ImageRecognitionPlugin) nnet.getPlugin(ImageRecognitionPlugin.class);	
           Log.i(TAG, "Neural network loaded");
           detectionScheduler.schedule(detectionTask, 0, DETECT_IMAGE_PERIOD);
        }
   };

Neuroph štúdio sme nakoniec nahradili vlastným programom.

Príklad tvarov:

Crc.jpg Sqr.jpg


Trénovanie neurónovej siete

Po neúspešnom trápení sa s Neuroph štúdiom pri trénovaní robota v rozpoznávaní tvarov sme sa rozhodli zahodiť celý Neuroph projekt a napísať si vlastný kód na trénovanie neurónovej siete.

Postup pri trénovaní:

  1. nafotili sme fotografie (každý tvar, vrátane null - prázneho papiera, z viacerých uhlov, vzdialeností a za rôznych svetelných podmienok)
  2. fotky sme poslali ako vstup do programu
  3. výstup sa zisťoval podľa názvu fotky (circle, square, null) a podľa toho sa sieť natrénovala

Ukážka implementácie trénovania neurónovej siete:

   import java.awt.image.BufferedImage;
   import java.awt.image.Raster;
   import java.io.File;
   import java.io.IOException;
   import java.util.ArrayList;
   import javax.imageio.ImageIO;
   import org.neuroph.contrib.imgrec.ImageRecognitionPlugin;
   import org.neuroph.contrib.imgrec.ImageRecognitionSample;
   import org.neuroph.contrib.imgrec.image.Dimension;
   import org.neuroph.core.NeuralNetwork;
   import org.neuroph.core.learning.SupervisedTrainingElement;
   import org.neuroph.core.learning.TrainingSet;
   import org.neuroph.nnet.MultiLayerPerceptron;
   import org.neuroph.util.TransferFunctionType;
   public class Run {
       public static final int INPUT_VECTOR_SIZE = 20*20*3;
       public static final int OUTPUT_VECTOR_SIZE = 3;
       public static void testNeural() {
           NeuralNetwork nn = NeuralNetwork.load("networks/latest.nnet");
           nn.setInput(getTrainingSet((new File("imgs/sqsq.png"))).getInput());
           nn.calculate();
           double[] output = nn.getOutput();
           for (double dd : output) {
               System.out.println(dd);
           }
   }
   public static void main(String[] args) {
       ArrayList<File> images = listFilesForFolder(new File("./imgs/"));
       TrainingSet<SupervisedTrainingElement> trainings = new TrainingSet<SupervisedTrainingElement>(INPUT_VECTOR_SIZE, OUTPUT_VECTOR_SIZE);
       for (File f :images) {
           trainings.addElement(getTrainingSet(f));
       }
       MultiLayerPerceptron mlp = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, INPUT_VECTOR_SIZE,  24, 12, OUTPUT_VECTOR_SIZE);    
       System.out.println("training");
       mlp.learn(trainings);
       mlp.save("./networks/latest.nnet");
       System.out.println("done");
   }
   public static SupervisedTrainingElement getTrainingSet(File file) {
       ArrayList<Double> input = null;
       ArrayList<Double> output = new ArrayList<>();
       //output
       if (file.getName().startsWith("circle")) {
           output.add(1.0d);
           output.add(0.0d);
           output.add(0.0d);
           System.out.println("Found circle: " + file.getName());
       } else if (file.getName().startsWith("other")) {
           output.add(0.0d);
           output.add(1.0d);
           output.add(0.0d);
           System.out.println("Found other: " + file.getName());
       }  else if (file.getName().startsWith("square")) {
           output.add(0.0d);
           output.add(0.0d);
           output.add(1.0d);
           System.out.println("Found square: " + file.getName());
       } 
       // input
       try {
           input = getInput(file);
       } catch (Exception e ) {
           e.printStackTrace();
       }
   return new SupervisedTrainingElement(input, output);
   }
   public static ArrayList<Double> getInput(File file) throws IOException {
       ArrayList<Double> input = new ArrayList<>();
       final BufferedImage bf = ImageIO.read(file);
       final Raster raster = bf.getData();
       for (int i = 0 ; i < raster.getHeight(); i++) {
           for (int j = 0; j < raster.getWidth(); j++) {
               double[] buff = new double[3];
               raster.getPixel(i, j, buff);
               input.add(buff[0] / 255.0d);
               input.add(buff[1] / 255.0d);
               input.add(buff[2] / 255.0d);
           }
       }
       return input;
   }
   public static ArrayList<File> listFilesForFolder(final File folder) {
       ArrayList<File> files = new ArrayList<File>();
       for (final File fileEntry : folder.listFiles()) {
           if (fileEntry.isDirectory()) {
           } else {
               files.add(fileEntry);
           }
       }
       return files;
   }
   }

Výsledky trénovania sú oveľa presnejšie a lepšie ako pri využívaní Neuroph štúdia.

Ukážka projektu

Robot sa v bludisku pohybuje smerom dopredu, keď nevidí žiaden zo znakov, ktoré pomocou neurónovej siete rozpoznáva. V tomto prípade verí, že vidí null - čiže nič. V prípade, že zbadá pomocou kamery mobilného telefónu, pripevneného na ňom znak modrý štvorec, robot sa začne točiť doľava. V prípade, že rozpozná v bludisku červený kruh, otáča sa doprava. Robot sa každých 750 ms pozrie na to, čo vidí a to vyhodnotí. Z tohto dôvodu je pohyb robota nespojitý. Obraz sa naškáluje na 20x20 pixlov.

Záver

Robot dokáže rozoznávať medzi červeným kruhom a modrým štvorcom. Robot pri rozpoznávaní tvarov preukazuje menšie chybovosti, vyplývajúce z natrénovania neurónovej siete. Sklon kamery, pripevnenej na robotovi, spôsobuje tiež menšie odchýlky. Pohyb je nespojitý.

Zdrojáky

Media:src2.zip

Zdroje

  1. Amarino toolkit
  2. Neuroph
  3. Motorika robota