v2_ test_lab setup
[The-Artvertiser.git] / garfeild / lightcalib / lightmap.h
blob6f1c1ef0e53e0339271128939033b4ef67ab8cd9
1 #ifndef _LIGHTMAP_H
2 #define _LIGHTMAP_H
4 #include <vector>
5 #include <math/growmat.h>
6 #include "lightcollector.h"
8 //also includes opengl
9 #include "ipltexture.h"
11 /*! \defgroup photocalib Photometric Calibration
12 * \ingroup garfeild
14 * Here's code to measure irradiance from images, to build an irradiance map
15 * and to use that map to augment a scene with OpenGL.
17 * The most interesting class here is LightMap. An example of augmentation can
18 * be found in \ref multigl.cpp.
20 /*!
21 * \ingroup photocalib
22 * \brief Irradiance map computation, storage and augmentation.
23 * \author Julien Pilet
25 * This class computes a environmental radiance map and uses OpenGL to augment
26 * 3D objects accordingly.
28 * The process to build a light map is the following: After geometric
29 * calibration, it becomes possible to turn an homography into a 3D pose (see
30 * CamAugmentation). Thus, when the planar target is detected on an image, it
31 * is possible to compute its normal in a reference coordinate system. It is
32 * also possible to compare its color with the model one. After collecting many
33 * views, a simple linear system computes gain and bias of each camera and the
34 * irradiance for each normal.
36 * All of this is done under lambertian assumption and might not behave very
37 * well in presence of specularities, specially in a multi-camera environment.
39 * Relighting 3D objects for augmentation can done by GPU using a vertex and a
40 * pixel shader.
42 class LightMap {
43 public:
44 LightMap();
45 ~LightMap();
46 LightMap(const LightMap &a);
48 bool init(int nbCam, IplImage *model, float corners[4][2], int nx, int ny);
49 void clear();
50 void setCamNum(int n);
52 bool initGL();
53 void enableShader(int cam, CvMat *obj2world);
54 void disableShader();
56 bool load(const char *lightParamsFN="lightParams.mat", const char *normalsFN="normals.mat");
57 bool save(const char *lightParamsFN="lightParams.mat", const char *normalsFN="normals.mat");
59 //! calls addNormalCalib if the system is not yet solved, or addNormallightMap otherwise.
60 bool addNormal(float normal[3], LightCollector &lc, int cam);
62 //! Add a normal for future light map computation
63 bool addNormalCalib(float normal[3], LightCollector &lc, int cam);
65 //! Update the current light map with given observation
66 bool addNormalLightMap(float normal[3], LightCollector &lc, int cam);
68 /*! Compute the light map using all available observations, previously
69 * added with addNormalCalib ir addNormal.
71 bool computeLightParams();
73 //! return true when computeLightParams() has succeeded.
74 bool isReady() { return lightParams!=0; }
76 //! Contains the irradiance map. Read it with readMap, update it with addNormal.
77 IplTexture map;
79 LightCollector reflc;
81 bool saveImage(const char *filename);
83 //! return the (B,G,R) gain of a camera.
84 const float *getGain(int cam);
85 //! return the (B,G,R) bias of a camera.
86 const float *getBias(int cam);
88 //! returns the irradiance for a given normal.
89 CvScalar readMap(const float normal[3]);
91 //! the number of normals measured that'll be used by computeLightParams.
92 int nbNormals() const { return normals->rows; }
94 private:
95 void normal2uv(const float n[3], float uv[2]);
96 void uv2normal(const float uv[2], float n[3]);
97 bool updateLightMap(float n[3], float *val);
98 double getObsMat(int i, int j, int c);
100 void buildMapFromSamples();
102 // (g, b) for each cam, x for each frame
103 struct Observation {
104 int camCol;
105 float camVal[3];
106 int normalCol;
107 float normalVal[3];
109 static double getObsElem(const std::vector<Observation>::iterator &it, int i, int c);
110 void computeAtA(CvMat *AtA, int channel);
112 std::vector<Observation> obs;
113 CvMat *lightParams;
114 CvGrowMat *normals;
115 int nbCam;
117 bool ARB;
118 bool initialized;
119 unsigned int g_vertShader, g_fragShader, g_shaderProgram;
122 #endif