Kiretu

/home/wu/Desktop/kiretu-0.8/KinectCloud.h

Go to the documentation of this file.
00001 /* This file is part of the Kiretu, a Kinect reconstruction tutor.
00002  * 
00003  * http://pille.iwr.uni-heidelberg.de/~kinect01/
00004  * 
00005  * The code ist licensed to you under the terms of the GNU General Public 
00006  * License, version 2.0. See the GPL2 file for the text of the license or the 
00007  * following URL:
00008  * 
00009  * http://www.gnu.org/licenses/gpl-2.0.txt
00010  * 
00011  * If you redistribute this file in source form, modified or unmodified, you
00012  * have to leave this header intact and distribute it under the same terms with 
00013  * the GPL2 file.
00014  * 
00015  * Binary distributions must follow the binary distribution requirements of
00016  * the License.
00017  * 
00018  */
00019  
00020  /** \file KinectCloud.h
00021  * 
00022  * Header file of the KinectCloud-class.
00023  * 
00024  * \author      Daniel Wunderlich (d.wunderlich@stud.uni-heidelberg.de)
00025  * \version     0.8
00026  * \date        2011-01-26
00027  * 
00028  * \see         KinectCloud
00029  */
00030 
00031 #include <vector>
00032 #include <iostream>
00033 #include <cmath>
00034 
00035 //~ #include <vcg/simplex/vertex/base.h>   
00036 //~ #include <vcg/simplex/vertex/component.h>
00037 //~ #include <vcg/space/normal_extrapolation.h>
00038 //~ #include <vcg/complex/used_types.h>
00039 
00040 #include "Util.h"
00041 //~ #include "NormalReconstruction.h"
00042 
00043 /** \class  KinectCloud 
00044  *  \brief  C++-class which represents a point-cloud of Microsoft's Kinect and 
00045  *          allows the reconstruction of a point-cloud applying the steps 
00046  *          explained at the documentation.
00047  *  
00048  *  \author     Daniel Wunderlich (d.wunderlich@stud.uni-heidelberg.de)
00049  *  \version    0.8
00050  *  \date       2011-01-26
00051  *  \see        \ref reconstruction and \ref kinectcloud-section
00052  */
00053 class KinectCloud {
00054     
00055     public:
00056 
00057 /** \brief Constructor of the KinectCloud-class.
00058  */ 
00059         KinectCloud();
00060 
00061 
00062 /** \brief Destructor of the KinectCloud-class.
00063  */ 
00064         ~KinectCloud();
00065 
00066 
00067 /** \brief  Adds the z-values of a Kinect depth-image grabbed by FrameGrabber 
00068  *          and stores them as a point-cloud (std::vector< std::vector<float> >).
00069  *  
00070  *  \param  zValues Pointer to a \f$640 \times 480\f$-dimensional array of 
00071  *                  z-values.
00072  */ 
00073         void addZValues(int* zValues);
00074 
00075 
00076 /** \brief  Adds the RGB-values of a Kinect RGB-image grabbed by FrameGrabber 
00077  *          and stores them as a point-cloud (std::vector< std::vector<float> >).   
00078  *  
00079  *  \param  rgbValues   Pointer to a \f$640 \times 480\f$-dimensional array of 
00080  *                      RGB-values.
00081  */ 
00082         void addRgbValues(int* rgbValues);
00083         
00084         //~ void undistortDepthImage(std::vector<float> depthDist);
00085         //~ void undistortRgbImage(std::vector<float> rgbDist);
00086 
00087 
00088 /** \brief  Converts the added depth-values of the Kinect (\f$ Z_\mathrm{raw} \in
00089  *          [0, 2047) \f$) into meter using the formula
00090  *          \f[
00091  *              Z_\mathrm{meter} = \frac{1}{Z_\mathrm{raw} \cdot (-0.0030711016) + 3.3309495161},
00092  *          \f]
00093  *          which was experimentaly determined (http://nicolas.burrus.name/index.php/Research/KinectCalibration).
00094  *          
00095  *          Consider that the z-values must be added (addZValues(int* zValues)) 
00096  *          before before calling this function.
00097  *  
00098  *  \see    \ref kinectcloud-step1
00099  */ 
00100         void rawToMeter();
00101 
00102 
00103 /** \brief  Applies the intrinsic camera-parameters to the point-cloud. The 
00104  *          parameters should be imported using YMLParser. With the help of 
00105  *          these parameters, each point \f$ (x,y)^T \f$ of the depth-image with 
00106  *          its depth-value \f$Z\f$ is projected on its equivalent point 
00107  *          \f$ (X,Y,Z)^T \f$ in 3D-space regarding its z-value and the 
00108  *          depth-camera-parameters. 
00109  *          This is done with the following formula:
00110  *          \f{align*}
00111  *              \begin{pmatrix} 
00112  *                  x_\mathsf{d} \\ y_\mathsf{d}\\ 1
00113  *              \end{pmatrix}
00114  *              &= 
00115  *              \begin{pmatrix}
00116  *                   & & & 0 \\
00117  *                   & \mathbf{C} & & 0 \\
00118  *                   & & & 0
00119  *              \end{pmatrix}
00120  *              \begin{pmatrix} 
00121  *                  X_\mathsf{d} \\ Y_\mathsf{d} \\ Z_\mathsf{d} \\ 1
00122  *              \end{pmatrix}
00123  *              =
00124  *              \begin{pmatrix} 
00125  *                  f_x & 0 & c_x & 0 \\
00126  *                  0 & f_y & c_y & 0 \\
00127  *                  0 & 0 & 1 & 0
00128  *              \end{pmatrix}
00129  *              \cdot
00130  *              \begin{pmatrix} 
00131  *                  X_\mathsf{d} \\ Y_\mathsf{d} \\ Z_\mathsf{d} \\ 1
00132  *              \end{pmatrix} \\
00133  *              &=
00134  *              \begin{pmatrix} 
00135  *                  f_x \cdot X_\mathsf{d} + c_x \cdot Z_\mathsf{d} \\ 
00136  *                  f_y \cdot Y_\mathsf{d} + c_y \cdot Z_\mathsf{d} \\ 
00137  *                  Z
00138  *              \end{pmatrix}
00139  *              =
00140  *              \begin{pmatrix} 
00141  *                  f_x \cdot X_\mathsf{d} / Z_\mathsf{d} + c_x \\ 
00142  *                  f_y \cdot Y_\mathsf{d} / Z_\mathsf{d} + c_y \\ 
00143  *                  1
00144  *              \end{pmatrix} \\
00145  *              &\Rightarrow\quad
00146  *              \begin{cases} 
00147  *                  X_\mathsf{d} = (x_\mathsf{d} - c_x) \cdot Z_\mathsf{d} / f_x \\
00148  *                  Y_\mathsf{d} = (y_\mathsf{d} - c_y) \cdot Z_\mathsf{d} / f_y
00149  *              \end{cases},
00150  *          \f}
00151  *          where \f$\mathbf{C}\f$ contains the intrinsic parameters of the 
00152  *          depth-camera. Notice that the z-value doesn't change during this 
00153  *          procedure and is already available at the depth-image.
00154  *          
00155  *          Consider that the extrinsic parameters should already be applied to 
00156  *          the point-cloud (applyExtrinsics(std::vector< std::vector<float> > rot, std::vector<float> trans)) 
00157  *          before calling this function.
00158  * 
00159  * \param   depthCam    Intrisic parameters of the depth-cam as a 
00160  *                      \f$ 3 \times 3 \f$-matrix as written in the specific 
00161  *                      yml-file and imported using YMLParser.
00162  * 
00163  * \see     \ref kinectcloud-step2
00164  */ 
00165         void depthToCloud(std::vector< std::vector<float> > depthCam);
00166 
00167 
00168 /** \brief  Applies the extrinsic camera-parameters to the point-cloud. The 
00169  *          parameters should be imported using YMLParser. This is done with a 
00170  *          rotation and translation of each point:
00171  *          \f[
00172  *              \begin{pmatrix} 
00173  *                  x_\mathrm{rgb} \\ y_\mathrm{rgb} \\ z_\mathrm{rgb}
00174  *              \end{pmatrix}
00175  *              = 
00176  *              R \cdot 
00177  *              \begin{pmatrix} 
00178  *                  x_\mathrm{d} \\ y_\mathrm{d} \\ z_\mathrm{d}
00179  *              \end{pmatrix}
00180  *              + T
00181  *              =
00182  *              \begin{pmatrix} 
00183  *                  r_{11} & r_{12} & r_{13} \\
00184  *                  r_{21} & r_{22} & r_{23} \\
00185  *                  r_{31} & r_{32} & r_{33}
00186  *              \end{pmatrix}
00187  *              \cdot
00188  *              \begin{pmatrix} 
00189  *                  x_\mathrm{d} \\ y_\mathrm{d} \\ z_\mathrm{d}
00190  *              \end{pmatrix}
00191  *              +
00192  *              \begin{pmatrix} 
00193  *                  t_1 \\ t_2 \\ t_3
00194  *              \end{pmatrix},
00195  *          \f]
00196  *          where \f$R\f$ and \f$T\f$ are the extrinsic parameters of the Kinect 
00197  *          and describe a rotation and translation.
00198  *          
00199  *          Consider that the z-values should be converted into meters 
00200  *          (rawToMeter()) before calling this function for a correct 
00201  *          reconstruction.
00202  * 
00203  * \param   rot     Rotation-matrix (\f$ 3 \times 3 \f$) of the Kinect as 
00204  *                  written in the specific yml-file and imported using 
00205  *                  YMLParser.
00206  *  \param  trans   Translation-vector (3-dimensional) of the Kinect as 
00207  *                  written in the specific yml-file and imported using 
00208  *                  YMLParser.
00209  * 
00210  * \see     \ref kinectcloud-step3
00211  */ 
00212         void applyExtrinsics(std::vector< std::vector<float> > rot, std::vector<float> trans);
00213         
00214         
00215 /** \brief  Computes the mapping between the point-cloud and the equivalent 
00216  *          points of the RGB-image by reprojecting the point 
00217  *          \f$ (X_\mathsf{rgb},Y_\mathsf{rgb},Z_\mathsf{rgb}) \f$ 
00218  *          of the point-cloud to its equivalent point 
00219  *          \f$ (x_\mathsf{rgb},y_\mathsf{rgb}) \f$ in the plane 
00220  *          using the intrinsics of the RGB-camera imported by YMLParser. The 
00221  *          projection is done with the following formula:
00222  *          \f{align*}
00223  *              \begin{pmatrix} 
00224  *                  x_\mathsf{rgb} \\ y_\mathsf{rgb} \\ 1
00225  *              \end{pmatrix}
00226  *              &= 
00227  *              \begin{pmatrix} 
00228  *                   &  & & 0 \\
00229  *                   & \mathbf{C} &  & 0 \\
00230  *                   &  & & 0 
00231  *              \end{pmatrix}
00232  *              \begin{pmatrix} 
00233  *                  X_\mathsf{rgb} \\ Y_\mathsf{rgb} \\ Z_\mathsf{rgb} \\ 1
00234  *              \end{pmatrix}
00235  *              =
00236  *              \begin{pmatrix} 
00237  *                  f_x & 0 & c_x & 0 \\
00238  *                  0 & f_y & c_y & 0 \\
00239  *                  0 & 0 & 1 & 0
00240  *              \end{pmatrix}
00241  *              \cdot
00242  *              \begin{pmatrix} 
00243  *                  X_\mathsf{rgb} \\ Y_\mathsf{rgb} \\ Z_\mathsf{rgb} \\ 1
00244  *              \end{pmatrix} \\
00245  *              &=
00246  *              \begin{pmatrix} 
00247  *                  f_x \cdot X_\mathsf{rgb} + c_x \cdot Z_\mathsf{rgb} \\ 
00248  *                  f_y \cdot Y_\mathsf{rgb} + c_y \cdot Z_\mathsf{rgb} \\ 
00249  *                  Z
00250  *              \end{pmatrix}
00251  * =
00252  *              \begin{pmatrix} 
00253  *                  f_x \cdot X_\mathsf{rgb} / Z + c_x \\ 
00254  *                  f_y \cdot Y_\mathsf{rgb} / Z + c_y \\ 
00255  *                  1
00256  *              \end{pmatrix} \\
00257  *              &\Rightarrow
00258  *              \begin{cases} 
00259  *                  x_\mathsf{rgb} = (f_x \cdot X_\mathsf{rgb} / Z_\mathsf{rgb}) + c_x \\
00260  *                  y_\mathsf{rgb} = (f_y \cdot Y_\mathsf{rgb} / Z_\mathsf{rgb}) + c_y
00261  *              \end{cases},
00262  *          \f}
00263  *          where \f$C\f$ contains the intrinsic parameters of the RGB-camera. 
00264  *          
00265  *          Consider that the depth-image needs to be projected into the 
00266  *          3D-space using (depthToCloud(std::vector< std::vector<float> > depthCam)) 
00267  *          before calling this function for correct reconstruction.
00268  * 
00269  * \param   rgbCam  Intrisic parameters of the RGB-cam as a 
00270  *                  \f$ 3 \times 3 \f$-matrix as written in the specific 
00271  *                  yml-file and imported using YMLParser.
00272  * 
00273  * \see     \ref kinectcloud-step4
00274  */ 
00275         void computeRgbMapping(std::vector< std::vector<float> > rgbCam);
00276         
00277         //~ void computeNormals();
00278 
00279 
00280 /** \brief Get the cloud.
00281  * 
00282  *  \return Vector of 3-dimensional points.
00283  */ 
00284         std::vector< std::vector<float> > getCloud();
00285 
00286 
00287 /** \brief Get the RGB-cloud.
00288  * 
00289  *  \return Vector of 3-dimensional vectors containing the RGB-values of the 
00290  *          cloud.
00291  */ 
00292         std::vector< std::vector<int> > getCloudRgb();
00293 
00294 
00295 /** \brief Get the cloud-RGB-mapping.
00296  * 
00297  *  \return Vector of 2-dimensional vectors, which contain the x- and y-value of 
00298  *          the pixel at the RGB-image of every point at the point-cloud. It is 
00299  *          used to find the corresponding color of every point of the 
00300  *          point-cloud at the RGB-image.
00301  */ 
00302         std::vector< std::vector<int> > getCloudRgbMapping();
00303         
00304         //~ std::vector< std::vector<float> > getNormals();
00305 
00306 
00307 /** \brief  Get a vector which indicates if a point of the point-cloud is valid
00308  *          (\f$depth < 2047\f$).
00309  * 
00310  *  \return Indicates for every of the \f$640 \times 480\f$ points if it is 
00311  *          valid (\f$depth < 2047\f$).
00312  */ 
00313         std::vector<bool> getValidValues();
00314 
00315 
00316 /** \brief Get the reconstruction-steps.
00317  * 
00318  *  \return Vector boolean values indicating if the reconstruction step was 
00319  *          done. The values of a returned vector \c recon indicate:
00320  *          \li \c recon[0]: Raw depth-values of the Kinect converted into 
00321  *              meters using rawToMeter().
00322  *          \li \c recon[1]: The intrinsic parameters of the depth-camera were 
00323  *              applied using 
00324  *              depthToCloud(std::vector< std::vector<float> > depthCam).
00325  *          \li \c recon[2]: The extrinsic camera-parameters were applied using 
00326  *              applyExtrinsics(std::vector< std::vector<float> > rot, std::vector<float> trans).
00327  *          \li \c recon[3]: The intrinsic parameters of the RGB-camera were 
00328  *              applied using  
00329  *              computeRgbMapping(std::vector< std::vector<float> > rgbCam).
00330  *          \li (\c recon[4]: Normals were reconstructed using
00331  *              computeNormals() &ndash; not implemented yet.)
00332  *          
00333  */ 
00334         std::vector<bool> getReconstructionSteps();
00335         
00336     private:
00337         std::vector< std::vector<float> > cloud;            /**< The point-cloud */
00338         std::vector< std::vector<int> > cloudRgb;           /**< The RGB-values */
00339         std::vector< std::vector<int> > cloudRgbMapping;    /**< Coordinates of a point's corresponding color at the RGB-image */
00340         //~ std::vector< std::vector<float> > normals;          /**< Normals */
00341         std::vector<bool> validValues;                      /**< Valid flags for each point */
00342         std::vector<bool> reconstructionSteps;              /**< Reconstruction flags */
00343     
00344 };
00345 
00346 
00347     
00348     //~ class VCGVertex;
00349     //~ class VCGUsedTypes : public vcg::UsedTypes<vcg::Use<VCGVertex>::AsVertexType> {};
00350     //~ class VCGVertex : public vcg::Vertex<VCGUsedTypes, vcg::vertex::Coord3d, vcg::vertex::Normal3d> {};
 All Data Structures Files Functions Variables Enumerations Enumerator
[Page Up]