summaryrefslogtreecommitdiff
path: root/2003
diff options
context:
space:
mode:
authorschodet2003-05-01 17:10:58 +0000
committerschodet2003-05-01 17:10:58 +0000
commit30ea7faee31ad69f3f0886dae8bb58e1fe31a74f (patch)
treeec61cfbc35f9a603f8ffd9e6c3ddb72b72a570e7 /2003
parentc306e33f3005ddb5a19c9aa590ef19560471137b (diff)
Ajout du module vision.
Diffstat (limited to '2003')
-rw-r--r--2003/i/buzz/src/busp/GNUmakefile2
-rw-r--r--2003/i/buzz/src/busp/busp.h2
-rw-r--r--2003/i/buzz/src/vision/GNUmakefile26
-rw-r--r--2003/i/buzz/src/vision/image.cc354
-rw-r--r--2003/i/buzz/src/vision/image.h44
-rw-r--r--2003/i/buzz/src/vision/rgbyuv.h57
-rw-r--r--2003/i/buzz/src/vision/size_thresholds.cc53
-rw-r--r--2003/i/buzz/src/vision/size_thresholds.h40
-rw-r--r--2003/i/buzz/src/vision/test_image.cc37
-rw-r--r--2003/i/buzz/src/vision/thresholds.cc55
-rw-r--r--2003/i/buzz/src/vision/thresholds.h42
11 files changed, 710 insertions, 2 deletions
diff --git a/2003/i/buzz/src/busp/GNUmakefile b/2003/i/buzz/src/busp/GNUmakefile
index 3fe815e..28efc6f 100644
--- a/2003/i/buzz/src/busp/GNUmakefile
+++ b/2003/i/buzz/src/busp/GNUmakefile
@@ -8,7 +8,7 @@ test_busp_SOURCES = busp.cc test_busp.cc $(SRCDIR)/erreur/erreur.a
all: $(TARGETS)
test_busp: $(test_busp_SOURCES:%.cc=%.o)
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ $(LDADD)
clean:
rm -f $(TARGETS) *.o
diff --git a/2003/i/buzz/src/busp/busp.h b/2003/i/buzz/src/busp/busp.h
index 767ac27..b7aa328 100644
--- a/2003/i/buzz/src/busp/busp.h
+++ b/2003/i/buzz/src/busp/busp.h
@@ -1,6 +1,6 @@
#ifndef busp_h
#define busp_h
-// busp.h
+// busp.h - Contrôle bas niveau du bus parallèle.
// buzz - Programme du robot Efrei Robotique I1-I2 2003
// Copyright (C) 2003 Nicolas Schodet
diff --git a/2003/i/buzz/src/vision/GNUmakefile b/2003/i/buzz/src/vision/GNUmakefile
new file mode 100644
index 0000000..b72985b
--- /dev/null
+++ b/2003/i/buzz/src/vision/GNUmakefile
@@ -0,0 +1,26 @@
+SRCDIR = ..
+CXXFLAGS = -Wall -g
+CPPFLAGS = -I$(SRCDIR)
+
+LDADD = -lppm
+test_image_SOURCES = test_image.cc image.cc thresholds.cc size_thresholds.cc
+
+TARGETS = test_image
+
+all: $(TARGETS)
+
+test_image: $(test_image_SOURCES:%.cc=%.o)
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ $(LDADD)
+
+.dep/%.d: %.cc .dep
+ @set -e; $(CC) -M $(CPPFLAGS) $< \
+ | sed 's/\($*\)\.o[ :]*/\1.o .dep\/$*.d : /g' > $@; \
+ [ -s $@ ] || rm -f $@
+
+include $(test_image_SOURCES:%.cc=.dep/%.d)
+
+.dep:
+ @mkdir .dep
+
+clean:
+ rm -f $(TARGETS) *.o
diff --git a/2003/i/buzz/src/vision/image.cc b/2003/i/buzz/src/vision/image.cc
new file mode 100644
index 0000000..f868587
--- /dev/null
+++ b/2003/i/buzz/src/vision/image.cc
@@ -0,0 +1,354 @@
+// image.cc - Classe Image
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+#include "image.h"
+#include "rgbyuv.h"
+
+// A definir si on code en YUV.
+//#define USE_YUV
+
+extern "C" {
+#include <ppm.h>
+};
+
+// Attention, l'un des paramètres est evalué deux fois.
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#define max(a,b) ((a) > (b) ? (a) : (b))
+
+// Constructeur.
+Image::Image (const char *filename, Thresholds *thresholds,
+ SizeThresholds *sizeThresholds)
+{
+ pixel **img;
+ pixel *p;
+ pixval maxval;
+ int x, y, w, h;
+#ifdef USE_YUV
+ int r, g, b, Y, U, V;
+#endif // USE_YUV
+ FILE *fp;
+ unsigned char *pi;
+ // Open the file.
+ fp = fopen (filename, "r");
+ if (!fp) throw "Image::Image: fopen failled";
+ // Read it.
+ img = ppm_readppm (fp, &w, &h, &maxval);
+ // Close it.
+ fclose (fp);
+ if (!img) throw "Image::Image: ppm_readppm failled";
+ // Allocate memory...
+ m_image = new unsigned char [w*h*3];
+ m_width = w;
+ m_height = h;
+ // Extrait les info RGB ou YUV.
+ pi = m_image;
+ for (y = 0; y < h; y++)
+ {
+ p = img[y];
+ for (x = 0; x < w; x++)
+ {
+#ifdef USE_YUV
+ r = PPM_GETR (*p) * 255 / maxval;
+ g = PPM_GETG (*p) * 255 / maxval;
+ b = PPM_GETB (*p) * 255 / maxval;
+ RgbYuv::rgbToYuv (r, g, b, Y, U, V);
+ *pi++ = (unsigned char) Y;
+ *pi++ = (unsigned char) U;
+ *pi++ = (unsigned char) V;
+#else // ! USE_YUV
+ *pi++ = (unsigned char) (PPM_GETR (*p) * 255 / maxval);
+ *pi++ = (unsigned char) (PPM_GETG (*p) * 255 / maxval);
+ *pi++ = (unsigned char) (PPM_GETB (*p) * 255 / maxval);
+#endif // ! USE_YUV
+ p++;
+ }
+ }
+ // Alloue de la memoire pour les zones.
+ m_zones = new unsigned char [m_width * m_height];
+ // Initalisation
+ m_groups = 0;
+ m_thresholds = thresholds;
+ m_sizeThresholds = sizeThresholds;
+}
+
+// Destructeur
+Image::~Image (void)
+{
+ ImageGroup *g, *g2;
+ if (m_image) delete [] m_image;
+ if (m_zones) delete [] m_zones;
+ for (g = m_groups; g; g = g2)
+ {
+ g2 = g->next;
+ delete g;
+ }
+}
+
+// Filtre l'image pour trouver les zones.
+void Image::filter (void)
+{
+ int i;
+ unsigned char *pz, *pi;
+ unsigned char r, g, b; // ou y, u, v, c'est le même traitement.
+ // Filtre.
+ pz = m_zones;
+ pi = m_image;
+ for (i = 0; i < m_width * m_height; i++)
+ {
+ r = *pi++;
+ g = *pi++;
+ b = *pi++;
+ *pz++ = m_thresholds->findZone (r, g, b);
+ }
+}
+
+// Group les groupes de pixels.
+void Image::group (void)
+{
+ // c: group courant, n: group suivant (chercheur).
+ ImageGroup *c, **n, *n2;
+ // Supprime tous les groupes.
+ for (c = m_groups; c; c = n2)
+ {
+ n2 = c->next;
+ delete c;
+ }
+ // Fait des groupes de pixels.
+ groupLine ();
+ for (c = m_groups; c; c = c->next)
+ {
+ n = &c->next;
+ // Recherche des groups plus bas dans l'image qui sont colle au groupe
+ // courant.
+ while (*n && (*n)->y <= c->y + c->h)
+ {
+ // Si ils sont de la même zone et qu'ils se touchent (avec au
+ // moins 5 pixels), on les rassemble en 1 groupe.
+ if (c->zone == (*n)->zone
+ && (*n)->x < c->x + c->w - 5
+ && c->x < (*n)->x + (*n)->w - 5)
+ {
+ // Dechainage de n.
+ n2 = (*n);
+ *n = n2->next;
+ // Mise a jour de c.
+ c->h++;
+ c->w = max (c->x + c->w, n2->x + n2->w) - min (c->x, n2->x);
+ c->x = min (c->x, n2->x);
+ // Supression de n.
+ delete n2;
+ }
+ else
+ n = &(*n)->next;
+ }
+ }
+}
+
+// Fait des packets de pixels sur les lignes.
+void Image::groupLine (void)
+{
+ unsigned char zone;
+ int n, y, x, sx;
+ ImageGroup **p;
+ unsigned char *pz;
+ pz = m_zones;
+ p = &m_groups;
+ for (y = 0; y < m_height; y++)
+ {
+ // Pour chaque ligne.
+ n = 0;
+ zone = 0;
+ for (x = 0; x < m_width; x++)
+ {
+ if (n == 0)
+ {
+ // Nouvelle zone.
+ sx = x;
+ zone = *pz;
+ n = 1;
+ }
+ else
+ {
+ if (zone == *pz)
+ {
+ // Même zone.
+ n++;
+ }
+ else
+ {
+ // Zone differente.
+ if (zone && n > 5)
+ {
+ *p = new ImageGroup;
+ (*p)->x = sx;
+ (*p)->y = y;
+ (*p)->w = n;
+ (*p)->h = 1;
+ (*p)->zone = zone;
+ (*p)->type = 0;
+ p = &(*p)->next;
+ }
+ n = 0;
+ zone = *pz;
+ }
+ }
+ pz++;
+ }
+ // Dernier groupe, si assez grand.
+ if (zone && n > 5)
+ {
+ *p = new ImageGroup;
+ (*p)->x = sx;
+ (*p)->y = y;
+ (*p)->w = n;
+ (*p)->h = 1;
+ (*p)->zone = zone;
+ (*p)->type = 0;
+ p = &(*p)->next;
+ }
+ }
+ *p = 0;
+}
+
+// Affiche les groupes qui on été trouvés.
+void
+Image::dumpGroups (void)
+{
+ ImageGroup *g;
+ printf ("Groups\n");
+ for (g = m_groups; g; g = g->next)
+ {
+ printf ("x: %d, y: %d, w: %d, h: %d, z: %d, t: %d\n", g->x, g->y,
+ g->w, g->h, g->zone, g->type);
+ }
+}
+
+// Filtre les packets de pixels.
+void
+Image::groupFilter (void)
+{
+ ImageGroup **g, *g2;
+ g = &m_groups;
+ while (*g)
+ {
+ g2 = *g;
+ // Trouve le type de palet.
+ g2->type = m_sizeThresholds->findType (g2->w, g2->h);
+ // Vire les groupes qu'on ne voix pas en entier ou d'une taille bizare.
+ if (g2->type == 0
+ || g2->x <= 0 || g2->x + g2->w >= m_width
+ || g2->y <= 0 || g2->y + g2->h >= m_height)
+ {
+ *g = g2->next;
+ delete g2;
+ }
+ else
+ {
+ g = &g2->next;
+ }
+ }
+}
+
+// Enregistre les infos trouvées.
+void
+Image::dump (const char *filename)
+{
+ pixel *row;
+ pixel *pr;
+ int x, y;
+ FILE *fp;
+ unsigned char *p;
+ int r, g, b;
+ ImageGroup *pg;
+ // Open the file.
+ fp = fopen (filename, "w");
+ if (!fp) throw "Image::dump: fopen failled";
+ // Allocate memory...
+ row = ppm_allocrow (m_width);
+ // Sauve l'image.
+#ifdef USE_YUV
+ ppm_writeppminit (fp, m_width, m_height * 4, 255, 0);
+#else // ! USE_YUV
+ ppm_writeppminit (fp, m_width, m_height * 3, 255, 0);
+#endif // ! USE_YUV
+ // image.
+ p = m_image;
+ for (y = 0; y < m_height; y++)
+ {
+ pr = row;
+ for (x = 0; x < m_width; x++)
+ {
+ r = *p++;
+ g = *p++;
+ b = *p++;
+ PPM_ASSIGN (*pr, r, g, b);
+ pr++;
+ }
+ ppm_writeppmrow (fp, row, m_width, 255, 0);
+ }
+#ifdef USE_YUV
+ // Image en couleurs RGB
+ p = m_image;
+ for (y = 0; y < m_height; y++)
+ {
+ pr = row;
+ for (x = 0; x < m_width; x++)
+ {
+ // Lit les YUV.
+ r = *p++;
+ g = *p++;
+ b = *p++;
+ // Convertit.
+ RgbYuv::yuvToRgb (r, g, b, r, g, b);
+ PPM_ASSIGN (*pr, r, g, b);
+ pr++;
+ }
+ ppm_writeppmrow (fp, row, m_width, 255, 0);
+ }
+#endif // USE_YUV
+ // Sauve les zones.
+ p = m_zones;
+ for (y = 0; y < m_height; y++)
+ {
+ pr = row;
+ for (x = 0; x < m_width; x++)
+ {
+ r = *p == 1 ? 255 : 0;
+ g = *p == 2 ? 255 : 0;
+ b = 0;
+ p++;
+ PPM_ASSIGN (*pr, r, g, b);
+ pr++;
+ }
+ ppm_writeppmrow (fp, row, m_width, 255, 0);
+ }
+ // Sauve les groupes.
+ for (y = 0; y < m_height; y++)
+ {
+ pr = row;
+ for (x = 0; x < m_width; x++)
+ {
+ r = g = b = 0;
+ for (pg = m_groups; pg; pg = pg->next)
+ {
+ if (x >= pg->x && x < pg->x + pg->w
+ && y >= pg->y && y < pg->y + pg->h)
+ {
+ if (pg->zone == 1)
+ r = 255;
+ else if (pg->zone == 2)
+ g = 255;
+ else
+ b = 255;
+ }
+ }
+ PPM_ASSIGN (*pr, r, g, b);
+ pr++;
+ }
+ ppm_writeppmrow (fp, row, m_width, 255, 0);
+ }
+ // Free memory.
+ ppm_freerow (row);
+ // Close it.
+ fclose (fp);
+}
diff --git a/2003/i/buzz/src/vision/image.h b/2003/i/buzz/src/vision/image.h
new file mode 100644
index 0000000..eae1d20
--- /dev/null
+++ b/2003/i/buzz/src/vision/image.h
@@ -0,0 +1,44 @@
+#ifndef image_h
+#define image_h
+// image.h - Image class
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+#include "thresholds.h"
+#include "size_thresholds.h"
+
+struct ImageGroup
+{
+ ImageGroup *next;
+ int x, y, w, h;
+ int zone, type;
+};
+
+class Image
+{
+ int m_width, m_height;
+ unsigned char *m_image;
+ unsigned char *m_zones;
+ ImageGroup *m_groups;
+ Thresholds *m_thresholds;
+ SizeThresholds *m_sizeThresholds;
+ public:
+ // Constructeur.
+ Image (const char *filename, Thresholds *thresholds,
+ SizeThresholds *sizeThresholds);
+ // Destructeur.
+ ~Image (void);
+ void filter (void);
+ // Fait des packets de pixels.
+ void group (void);
+ // Affiche les groupes qui on été trouvés.
+ void dumpGroups (void);
+ // Enregistre les infos trouvées.
+ void dump (const char *filename);
+ // Filtre les packets de pixels.
+ void groupFilter (void);
+ protected:
+ // Fait des packets de pixels sur les lignes.
+ void groupLine (void);
+};
+
+#endif // image_h
diff --git a/2003/i/buzz/src/vision/rgbyuv.h b/2003/i/buzz/src/vision/rgbyuv.h
new file mode 100644
index 0000000..104c309
--- /dev/null
+++ b/2003/i/buzz/src/vision/rgbyuv.h
@@ -0,0 +1,57 @@
+#ifndef rgbyuv_h
+#define rgbyuv_h
+// rgbyuv.h - Convertions RGB <-> YUV
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+
+// TODO: Implementer une version plus rapide avec des tableaux ???
+// Pas pour le momment, on utilise pas YUV.
+
+class RgbYuv
+{
+ public:
+ // Convertie un pixel RGB en YUV.
+ static void rgbToYuv (unsigned char r, unsigned char g, unsigned char b,
+ unsigned char &y, unsigned char &u, unsigned char
+ &v);
+ // Convertie un pixel YUV en RGB.
+ static void yuvToRgb (unsigned char y, unsigned char u, unsigned char v,
+ unsigned char &r, unsigned char &g, unsigned char
+ &b);
+};
+
+// Convertie un pixel RGB en YUV.
+inline void RgbYuv::rgbToYuv (unsigned char r, unsigned char g, unsigned char
+ b, unsigned char &y, unsigned char &u, unsigned
+ char &v)
+{
+ y = (( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
+ u = (( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
+ v = (( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
+}
+
+// Convertie un pixel YUV en RGB.
+inline void RgbYuv::yuvToRgb (unsigned char y, unsigned char u, unsigned char
+ v, unsigned char &r, unsigned char &g, unsigned
+ char &b)
+{
+ int c, d, e;
+ int _r, _g, _b;
+ c = (int) (y & 0xff) - 16;
+ d = (int) (u & 0xff) - 128;
+ e = (int) (v & 0xff) - 128;
+ _r = (298 * c + 409 * e + 128) >> 8;
+ _g = (298 * c - 100 * d - 208 * e + 128) >> 8;
+ _b = (298 * c + 516 * d + 128) >> 8;
+ if (_r > 255) _r = 255;
+ if (_g > 255) _g = 255;
+ if (_b > 255) _b = 255;
+ if (_r < 0) _r = 0;
+ if (_g < 0) _g = 0;
+ if (_b < 0) _b = 0;
+ r = _r;
+ g = _g;
+ b = _b;
+}
+
+#endif // rgbyuv_h
diff --git a/2003/i/buzz/src/vision/size_thresholds.cc b/2003/i/buzz/src/vision/size_thresholds.cc
new file mode 100644
index 0000000..3a65d4c
--- /dev/null
+++ b/2003/i/buzz/src/vision/size_thresholds.cc
@@ -0,0 +1,53 @@
+// size_thresholds.cc - Chargement de seuils de taille de palets.
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+#include "size_thresholds.h"
+
+#include <stdio.h>
+
+// Constructeur.
+SizeThresholds::SizeThresholds (const char *filename)
+{
+ FILE *fp;
+ SizeThreshold **pt;
+ int n;
+ int type, wm, wM, hm, hM;
+ // Ouvre le fichier.
+ fp = fopen (filename, "r");
+ if (!fp) throw "SizeThresholds::SizeThresholds: fopen failled";
+ // Charge chaque lignes.
+ pt = &m_thresholds;
+ while (!feof (fp))
+ {
+ n = fscanf (fp, "%d %d %d %d %d\n", &type, &wm, &wM,
+ &hm, &hM);
+ if (n != 5)
+ {
+ fclose (fp);
+ throw "SizeThresholds::SizeThresholds: Bad format.";
+ }
+ // Ajoute un nouveaux seuil a la collection.
+ *pt = new SizeThreshold;
+ (*pt)->type = type;
+ (*pt)->wm = wm;
+ (*pt)->wM = wM;
+ (*pt)->hm = hm;
+ (*pt)->hM = hM;
+ pt = &(*pt)->next;
+ }
+ // Ferme la liste de seuils.
+ *pt = 0;
+ // Ferme le fichier.
+ fclose (fp);
+}
+
+// Destructeur.
+SizeThresholds::~SizeThresholds (void)
+{
+ SizeThreshold *p, *p2;
+ for (p = m_thresholds; p; p = p2)
+ {
+ p2 = p->next;
+ delete p;
+ }
+}
diff --git a/2003/i/buzz/src/vision/size_thresholds.h b/2003/i/buzz/src/vision/size_thresholds.h
new file mode 100644
index 0000000..f30ac4d
--- /dev/null
+++ b/2003/i/buzz/src/vision/size_thresholds.h
@@ -0,0 +1,40 @@
+#ifndef __size_thresholds_h__
+#define __size_thresholds_h__
+// size_thresholds.h - Chargement de seuils pour les tailles de palets.
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+
+struct SizeThreshold
+{
+ SizeThreshold *next;
+ int wm, wM, hm, hM;
+ int type;
+};
+
+class SizeThresholds
+{
+ SizeThreshold *m_thresholds;
+ public:
+ SizeThresholds (const char *filename);
+ ~SizeThresholds (void);
+ // Trouve le type qui correspond a la taille.
+ int findType (int w, int h);
+};
+
+// Trouve la zone qui correspond aux composantes.
+inline int
+SizeThresholds::findType (int w, int h)
+{
+ SizeThreshold *t;
+ for (t = m_thresholds; t; t = t->next)
+ {
+ if (w >= t->wm && w <= t->wM
+ && h >= t->hm && h <= t->hM)
+ {
+ return t->type;
+ }
+ }
+ return 0;
+}
+
+#endif // size_thresholds_h
diff --git a/2003/i/buzz/src/vision/test_image.cc b/2003/i/buzz/src/vision/test_image.cc
new file mode 100644
index 0000000..cbdbd1e
--- /dev/null
+++ b/2003/i/buzz/src/vision/test_image.cc
@@ -0,0 +1,37 @@
+// test_image.cc - Teste la classe Image.
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+#include "image.h"
+
+extern "C" {
+#include <ppm.h>
+};
+
+int
+main (int argc, char **argv)
+{
+ Image *i;
+ Thresholds *t;
+ SizeThresholds *st;
+ ppm_init (&argc, argv);
+ try
+ {
+ t = new Thresholds ("palets.rgb");
+ st = new SizeThresholds ("palets.size");
+ i = new Image (argc == 2 ? argv[1] : "test.ppm", t, 0);
+ i->filter ();
+ i->group ();
+ i->groupFilter ();
+ i->dumpGroups ();
+ i->dump ("dump.ppm");
+ delete i;
+ delete t;
+ delete st;
+ }
+ catch (const char *s)
+ {
+ fprintf (stderr, "test_image: %s\n", s);
+ return 1;
+ }
+ return 0;
+}
diff --git a/2003/i/buzz/src/vision/thresholds.cc b/2003/i/buzz/src/vision/thresholds.cc
new file mode 100644
index 0000000..23c37e5
--- /dev/null
+++ b/2003/i/buzz/src/vision/thresholds.cc
@@ -0,0 +1,55 @@
+// Classe Thresholds - Chargement de seuils
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+#include "thresholds.h"
+
+#include <stdio.h>
+
+// Constructeur.
+Thresholds::Thresholds (const char *filename)
+{
+ FILE *fp;
+ Threshold **pt;
+ int n;
+ int zone, ym, yM, um, uM, vm, vM;
+ // Ouvre le fichier.
+ fp = fopen (filename, "r");
+ if (!fp) throw "Thresholds::Thresholds: fopen failled";
+ // Charge chaque lignes.
+ pt = &m_thresholds;
+ while (!feof (fp))
+ {
+ n = fscanf (fp, "%d %d %d %d %d %d %d\n", &zone, &ym, &yM, &um,
+ &uM, &vm, &vM);
+ if (n != 7)
+ {
+ fclose (fp);
+ throw "Thresholds::Thresholds: Bad format.";
+ }
+ // Ajoute un nouveaux seuil a la collection.
+ *pt = new Threshold;
+ (*pt)->zone = zone;
+ (*pt)->ym = ym;
+ (*pt)->yM = yM;
+ (*pt)->um = um;
+ (*pt)->uM = uM;
+ (*pt)->vm = vm;
+ (*pt)->vM = vM;
+ pt = &(*pt)->next;
+ }
+ // Ferme la liste de seuils.
+ *pt = 0;
+ // Ferme le fichier.
+ fclose (fp);
+}
+
+// Destructeur.
+Thresholds::~Thresholds (void)
+{
+ Threshold *p, *p2;
+ for (p = m_thresholds; p; p = p2)
+ {
+ p2 = p->next;
+ delete p;
+ }
+}
diff --git a/2003/i/buzz/src/vision/thresholds.h b/2003/i/buzz/src/vision/thresholds.h
new file mode 100644
index 0000000..b11c387
--- /dev/null
+++ b/2003/i/buzz/src/vision/thresholds.h
@@ -0,0 +1,42 @@
+#ifndef thresholds_h
+#define thresholds_h
+// thresholds.h - Chargement de seuils.
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+
+struct Threshold
+{
+ Threshold *next;
+ unsigned char ym, yM, um, uM, vm, vM;
+ unsigned char zone;
+};
+
+class Thresholds
+{
+ Threshold *m_thresholds;
+ public:
+ Thresholds (const char *filename);
+ ~Thresholds (void);
+ // Trouve la zone qui correspond aux composantes.
+ unsigned char findZone (unsigned char y, unsigned char u, unsigned char
+ v);
+};
+
+// Trouve la zone qui correspond aux composantes.
+inline unsigned char
+Thresholds::findZone (unsigned char y, unsigned char u, unsigned char v)
+{
+ Threshold *t;
+ for (t = m_thresholds; t; t = t->next)
+ {
+ if (y >= t->ym && y <= t->yM
+ && u >= t->um && u <= t->uM
+ && v >= t->vm && v <= t->vM)
+ {
+ return t->zone;
+ }
+ }
+ return 0;
+}
+
+#endif // thresholds_h