summaryrefslogtreecommitdiff
path: root/2004/i/nono/src/camera
diff options
context:
space:
mode:
authorschodet2004-02-07 16:55:41 +0000
committerschodet2004-02-07 16:55:41 +0000
commit9fdd6704947174fae292dfc6e14cc1029a7f7a6c (patch)
tree40a4fe775845ececdaf27e82d99d6a06f6b3803e /2004/i/nono/src/camera
parentb673946d76e436c067d24e535b1e0a167b9dfc47 (diff)
Initial revision
Diffstat (limited to '2004/i/nono/src/camera')
-rw-r--r--2004/i/nono/src/camera/Makefile.defs11
-rw-r--r--2004/i/nono/src/camera/camera.cc173
-rw-r--r--2004/i/nono/src/camera/camera.h28
-rw-r--r--2004/i/nono/src/camera/dumpimage.cc36
-rw-r--r--2004/i/nono/src/camera/test_camera.cc64
5 files changed, 312 insertions, 0 deletions
diff --git a/2004/i/nono/src/camera/Makefile.defs b/2004/i/nono/src/camera/Makefile.defs
new file mode 100644
index 0000000..6c85f1b
--- /dev/null
+++ b/2004/i/nono/src/camera/Makefile.defs
@@ -0,0 +1,11 @@
+TARGETS += test_camera dumpimage
+LIBS += camera.a
+test_camera_SOURCES = camera.cc test_camera.cc erreur.a config.a date.a
+dumpimage_SOURCES = camera.cc dumpimage.cc erreur.a config.a date.a
+camera_a_SOURCES = camera.cc
+
+dumpimage: $(dumpimage_SOURCES:%.cc=%.o)
+
+test_camera: $(test_camera_SOURCES:%.cc=%.o)
+
+camera.a: ${camera_a_SOURCES:%.cc=camera.a(%.o)}
diff --git a/2004/i/nono/src/camera/camera.cc b/2004/i/nono/src/camera/camera.cc
new file mode 100644
index 0000000..52a038e
--- /dev/null
+++ b/2004/i/nono/src/camera/camera.cc
@@ -0,0 +1,173 @@
+// camera.cc
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+//
+#include "camera.h"
+#include "erreur/erreur.h"
+#include "kernel_mips/pbus.h"
+#include "config/config.h"
+#include "date/date.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <iostream> // Debug.
+#include <iomanip> //
+#include <fstream>
+
+using namespace std;
+
+#define CAM_FILE "/dev/robotcam"
+
+#define CAMERA_DEBUG
+
+// Constructeur.
+Camera::Camera ()
+{
+ // Taille par défaut.
+ m_w = 352; m_h = 288; m_d = 1;
+ m_cut = 0;
+ // Ouvre le périphérique.
+ m_fd = open (CAM_FILE, O_RDONLY);
+ if (m_fd == -1)
+ throw ErreurFatale ("Impossible d'ouvrir le périphérique de la"
+ " camera.\n");
+ // Paramètre la camera.
+ sccb_io param;
+ Config rc ("rc/camera");
+ int addr, data;
+ while (!rc.eof ())
+ {
+ if (rc.isId ("width"))
+ {
+ rc.getId ();
+ m_w = rc.getNum ();
+#ifdef CAMERA_DEBUG
+ cout << "camera width " << m_w << endl;
+#endif // CAMERA_DEBUG
+ }
+ else if (rc.isId ("height"))
+ {
+ rc.getId ();
+ m_h = rc.getNum ();
+#ifdef CAMERA_DEBUG
+ cout << "camera height " << m_h << endl;
+#endif // CAMERA_DEBUG
+ }
+ else if (rc.isId ("depth"))
+ {
+ rc.getId ();
+ m_d = rc.getNum ();
+#ifdef CAMERA_DEBUG
+ cout << "camera depth " << m_d << endl;
+#endif // CAMERA_DEBUG
+ }
+ else if (rc.isId ("cut"))
+ {
+ rc.getId ();
+ m_cut = rc.getNum ();
+#ifdef CAMERA_DEBUG
+ cout << "camera cut " << m_cut << endl;
+#endif // CAMERA_DEBUG
+ }
+ else if (rc.isId ("setup"))
+ {
+ rc.getId ();
+ addr = rc.getNum ();
+ data = rc.getNum ();
+ param.addr = addr; param.data = data;
+#ifdef CAMERA_DEBUG
+ cout << "camera sccbwrite 0x" << hex << addr << " 0x" << data <<
+ endl;
+#endif // CAMERA_DEBUG
+ ioctl (m_fd, CAM_SCCBWRITE, &param);
+ }
+ else
+ rc.noId ();
+ }
+ // Affiche les paramètres.
+#ifdef CAMERA_DEBUG
+ cout << hex << "camera sccbdump";
+ for (addr = 0; addr < 0x50; ++addr)
+ {
+ if (!(addr % 16)) cout << endl;
+ param.addr = addr;
+ ioctl (m_fd, CAM_SCCBREAD, &param);
+ data = param.data;
+ cout << setw (2) << setfill ('0') << data << ' ';
+
+ }
+ cout << endl << dec;
+#endif // CAMERA_DEBUG
+ m_lastRead = 0;
+ // Paramètre la taille de frame.
+ int hcount = m_w * m_d;
+ ioctl (m_fd, CAM_SETHCOUNT, &hcount);
+ m_frameSize = m_w * m_h * m_d + m_cut;
+ ioctl (m_fd, CAM_SETFRAMESIZE, &m_frameSize);
+}
+
+// Destructeur.
+Camera::~Camera ()
+{
+ // Ferme le périphérique de camera.
+ close (m_fd);
+}
+
+// Lit une image.
+int
+Camera::read (unsigned char *image)
+{
+ int r;
+ int t = Date::getInstance ().start ();
+ // Attention, pas trops vite.
+ if (m_lastRead + 100 > t)
+ return 0;
+ m_lastRead = t;
+ // Lit les données sur la camera.
+ if (m_cut)
+ r = ::read (m_fd, image, m_cut);
+ if (!m_cut || r)
+ r = ::read (m_fd, image, m_frameSize - m_cut);
+#ifdef CAMERA_DEBUG
+ cout << "camera read " << r << endl;
+#endif // CAMERA_DEBUG
+ return r;
+}
+
+// Lit une image en RGB.
+int
+Camera::readRGB (unsigned char *rgb)
+{
+ int ret;
+ int t = Date::getInstance ().start ();
+ // Attention, pas trops vite.
+ if (m_lastRead + 100 > t)
+ return 0;
+ m_lastRead = t;
+ // Alloue de la mémoire.
+ unsigned char *image = new unsigned char[m_frameSize];
+ // Lit les données sur la camera.
+ ret = ::read (m_fd, image, m_frameSize);
+#ifdef CAMERA_DEBUG
+ cout << "camera read " << ret << endl;
+#endif // CAMERA_DEBUG
+ if (!ret) return 0;
+ // Positions de débuts.
+ unsigned char *r, *g, *b;
+ r = image + m_cut + 2;
+ g = image + m_cut + 1;
+ b = image + m_cut;
+ // Décode les couleurs.
+ for (int i = 0; i < m_w * m_h; ++i)
+ {
+ *rgb++ = *r;
+ r += 4;
+ *rgb++ = *g;
+ g += 4;
+ *rgb++ = *b;
+ b += 4;
+ }
+ delete image;
+ return ret - m_cut;
+}
+
diff --git a/2004/i/nono/src/camera/camera.h b/2004/i/nono/src/camera/camera.h
new file mode 100644
index 0000000..b6c003e
--- /dev/null
+++ b/2004/i/nono/src/camera/camera.h
@@ -0,0 +1,28 @@
+#ifndef camera_h
+#define camera_h
+// camera.h
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+
+class Camera
+{
+ int m_fd;
+ int m_w, m_h, m_d;
+ int m_cut;
+ int m_frameSize;
+ int m_lastRead;
+ public:
+ // Constructeur.
+ Camera ();
+ // Destructeur.
+ ~Camera ();
+ // Lit une image.
+ int read (unsigned char *image);
+ // Lit une image en RGB.
+ int readRGB (unsigned char *rgb);
+ // Lit la taille.
+ void getSize (int &w, int &h) const { w = m_w; h = m_h; }
+ void getSize (int &w, int &h, int &d) const { w = m_w; h = m_h; d = m_d; }
+};
+
+#endif // camera_h
diff --git a/2004/i/nono/src/camera/dumpimage.cc b/2004/i/nono/src/camera/dumpimage.cc
new file mode 100644
index 0000000..90909af
--- /dev/null
+++ b/2004/i/nono/src/camera/dumpimage.cc
@@ -0,0 +1,36 @@
+// dumpimage.cc
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+//
+#include "camera.h"
+#include "date/date.h"
+
+#include <iomanip>
+#include <unistd.h>
+
+int
+main (int argc, char **argv)
+{
+ Camera cam;
+ Date date;
+ int w, h, d;
+ cam.getSize (w, h, d);
+ unsigned char *image = new unsigned char[w * h * d];
+ cout << hex;
+ int j = 0;
+ int pixel;
+ while (1)
+ {
+ cout << dec << "\n- " << j++ << hex << " ---------";
+ while (cam.read (image) == 0);
+ for (int i = 0; i < 256; ++i)
+ {
+ if (!(i % 16))
+ cout << endl;
+ pixel = image[i];
+ cout << setw (2) << setfill ('0') << pixel << ' ';
+ }
+ }
+ delete image;
+ return 0;
+}
diff --git a/2004/i/nono/src/camera/test_camera.cc b/2004/i/nono/src/camera/test_camera.cc
new file mode 100644
index 0000000..9b616af
--- /dev/null
+++ b/2004/i/nono/src/camera/test_camera.cc
@@ -0,0 +1,64 @@
+// test_camera.cc
+// buzz - Programme du robot Efrei Robotique I1-I2 2003
+// Copyright (C) 2003 Nicolas Schodet
+//
+#include "camera.h"
+#include "erreur/erreur.h"
+#include "date/date.h"
+
+#include <fstream>
+#include <unistd.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ try
+ {
+ Camera cam;
+ Date date;
+ sleep (5);
+ int w, h, d;
+ cam.getSize (w, h, d);
+ unsigned char *image = new unsigned char[w * h * d];
+ unsigned char *image2 = new unsigned char[w * h * 3];
+ for (int i = 0; i < 10; ++i)
+ {
+ char s[256];
+ sprintf (s, "camera%d.gray", i);
+ ofstream o (s);
+ while (cam.read (image) == 0) sleep (1);
+ o.write (image, w * h * d);
+ o.close ();
+ if (d == 4)
+ {
+ for (int j = 0; j < w * h; ++j)
+ {
+ image2[j * 3] = image[j * 4 + 2];
+ image2[j * 3 + 1] = image[j * 4 + 1];
+ image2[j * 3 + 2] = image[j * 4];
+ }
+ sprintf (s, "camera%d.rgb", i);
+ o.open (s);
+ o.write (image2, w * h * 3);
+ o.close ();
+ }
+ for (int j = 0; j < w * h; ++j)
+ {
+ int t = ((int) image[j * 4 + 2] >> 1) - ((int) image[j * 4 + 1] >> 1);
+ t = t > 0 ? t : -t;
+ image2[j] = t;
+ }
+ sprintf (s, "camera%d.diff.gray", i);
+ o.open (s);
+ o.write (image2, w * h);
+ o.close ();
+ }
+ return 0;
+ }
+ catch (Erreur &e)
+ {
+ cout << e.what ();
+ return 1;
+ }
+}