scene_recog.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *  Software License Agreement (BSD License)
00003 *  Copyright (c) 2013, Intelligent Robotics Lab, DLUT.
00004 *  All rights reserved.
00005 *  Author:Zhao Cilang,Yan Fei,Zhuang Yan
00006 *  Redistribution and use in source and binary forms, with or without
00007 *  modification, are permitted provided that the following conditions
00008 *  are met:
00009 *
00010 *   * Redistributions of source code must retain the above copyright
00011 *     notice, this list of conditions and the following disclaimer.
00012 *   * Redistributions in binary form must reproduce the above
00013 *     copyright notice, this list of conditions and the following
00014 *     disclaimer in the documentation and/or other materials provided
00015 *     with the distribution.
00016 *   * Neither the name of the Intelligent Robotics Lab nor the names of its
00017 *     contributors may be used to endorse or promote products derived
00018 *     from this software without specific prior written permission.
00019 *
00020 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 *  POSSIBILITY OF SUCH DAMAGE.
00032 *********************************************************************/
00033 #include <stdio.h>
00034 #include <fstream>
00035 #include <iostream>
00036 #include <ctype.h>
00037 #include <ctime>
00038 #include "camera_laser_calibration/scene_recog/scene_recog.h"
00039 
00040 #include <ros/ros.h>
00041 
00042 CSceneRecog *p_plane_display = NULL;
00043 
00044 CSceneRecog::CSceneRecog ()
00045 {
00046   L_width_ = 0;
00047   L_height_ = 0;
00048   p_plane_display = this;
00049   plane_parameters_[0] = 0.0;
00050   plane_parameters_[1] = 0.0;
00051   plane_parameters_[2] = 0.0;
00052   plane_parameters_[3] = 0.0;
00053 }
00054 
00055 CSceneRecog::~CSceneRecog (void)
00056 {
00057 }
00058 
00059 void CSceneRecog::srProcess (std::vector < std::vector < CPoint3d > >&data)
00060 {
00061   laser_data_.swap (data);      // copy the data
00062   srPlaneExtract ();            // data processing
00063   srStructureExtract ();
00064 }
00065 
00066 void CSceneRecog::srPlaneExtract ()
00067 {
00068   CPoint3d PointInSquare[DIMEN][DIMEN];
00069   CPoint3d Mv;
00070   CPoint3d Nvec;
00071   int flagbuf;
00072   int pnum = -1;
00073   if (laser_data_.size () > 0)
00074   {
00075     L_width_ = (int) laser_data_.size ();
00076     L_height_ = (int) laser_data_[0].size ();
00077 
00078     std::vector < CPointTag > TagVector (L_height_);
00079     std::vector < std::vector < CPointTag > >PTV (L_width_, TagVector);
00080     point_tag_vector_.swap (PTV);
00081 
00082     for (int i = 0; i < L_width_ - DIMEN; i = i + 1)
00083     {
00084       for (int j = 0; j < L_height_ - DIMEN; j = j + 1)
00085       {
00086         Mv.x = Mv.y = Mv.z = 0.0;
00087         for (int k = 0; k < DIMEN; k++) //get the fitting small planes
00088           for (int l = 0; l < DIMEN; l++)
00089           {
00090             PointInSquare[k][l] = laser_data_[i + k][j + l];
00091             Mv.x += PointInSquare[k][l].x;
00092             Mv.y += PointInSquare[k][l].y;
00093             Mv.z += PointInSquare[k][l].z;
00094           }
00095         Mv.x = Mv.x / (DIMEN * DIMEN);  // calculate the barycenter of small planes
00096         Mv.y = Mv.y / (DIMEN * DIMEN);
00097         Mv.z = Mv.z / (DIMEN * DIMEN);
00098 
00099         if (srIsAPlane (PointInSquare, Mv))
00100         {
00101           Nvec =srNormalVec (laser_data_[i + DIMEN - 1][j + DIMEN - 1], laser_data_[i + DIMEN - 1][j],
00102                              laser_data_[i][j + DIMEN - 1], laser_data_[i][j]);
00103 
00104           flagbuf = -1;
00105           for (int f = 0; f <= DIMEN - 1; f++)
00106             for (int g = 0; g <= DIMEN - 1; g++)
00107             {
00108               if (point_tag_vector_[i + f][j + g].pflag != -1)
00109               {
00110                 flagbuf = point_tag_vector_[i + f][j + g].pflag;
00111                 break;
00112               }
00113             }
00114 
00115           if (flagbuf == -1)
00116           {
00117             pnum++;
00118             for (int m = 0; m < DIMEN; m++)
00119             {
00120               for (int n = 0; n < DIMEN; n++)
00121               {
00122                 point_tag_vector_[i + m][j + n].pflag = pnum;
00123               }
00124             }
00125             Plane pTag;
00126             pTag.VecNum = 1;
00127             pTag.VecSum = Nvec;
00128             pTag.VecAve = Nvec;
00129             pTag.MeanVal = Mv;
00130             pTag.MeanSum = Mv;
00131             plane_vector_.push_back (pTag);
00132           }
00133           //there are points coincided in adjacent cells
00134           else
00135           {
00136             if (srAngle (plane_vector_[flagbuf].VecAve, Nvec) < 0.2 /*4*M_PI/180 */ )
00137             {
00138               for (int m2 = 0; m2 < DIMEN; m2++)
00139                 for (int n2 = 0; n2 < DIMEN; n2++)
00140                 {
00141                   point_tag_vector_[i + m2][j + n2].pflag = flagbuf;
00142                 }
00143 
00144               plane_vector_[flagbuf].VecNum++;
00145               //calculate the sum of normals
00146               plane_vector_[flagbuf].VecSum.x += Nvec.x;
00147               plane_vector_[flagbuf].VecSum.y += Nvec.y;
00148               plane_vector_[flagbuf].VecSum.z += Nvec.z;
00149               //calculate the normals
00150               plane_vector_[flagbuf].VecAve.x = plane_vector_[flagbuf].VecSum.x / plane_vector_[flagbuf].VecNum;
00151               plane_vector_[flagbuf].VecAve.y = plane_vector_[flagbuf].VecSum.y / plane_vector_[flagbuf].VecNum;
00152               plane_vector_[flagbuf].VecAve.z = plane_vector_[flagbuf].VecSum.z / plane_vector_[flagbuf].VecNum;
00153               //calculate the sum of barycenter
00154               plane_vector_[flagbuf].MeanSum.x += Mv.x;
00155               plane_vector_[flagbuf].MeanSum.y += Mv.y;
00156               plane_vector_[flagbuf].MeanSum.z += Mv.z;
00157               //calculate the barycenter
00158               plane_vector_[flagbuf].MeanVal.x = plane_vector_[flagbuf].MeanSum.x / plane_vector_[flagbuf].VecNum;
00159               plane_vector_[flagbuf].MeanVal.y = plane_vector_[flagbuf].MeanSum.y / plane_vector_[flagbuf].VecNum;
00160               plane_vector_[flagbuf].MeanVal.z = plane_vector_[flagbuf].MeanSum.z / plane_vector_[flagbuf].VecNum;
00161             }
00162           }
00163         }
00164       }
00165     }
00166   }
00167 }
00168 
00169 void CSceneRecog::srStructureExtract () //recover scene frame in indoor scene
00170 {
00171 
00172   using namespace std;
00173 
00174   for (int i = 0; i < L_height_; i++)
00175   {
00176     for (int j = 0; j < L_width_; j++)
00177     {
00178       int flag = point_tag_vector_[j][i].pflag;
00179       if (flag >= 0)
00180       {
00181         CPointIndex index (i, j);
00182         plane_vector_[flag].InnerPoints.push_back (index);
00183       }
00184     }
00185   }
00186 
00187 
00188   // sort by plane size descending
00189   int PlaneNum = (int) plane_vector_.size ();
00190   for (int i = 0; i < PlaneNum - 1; i++)
00191   {
00192     int pmax = i;
00193     for (int j = i + 1; j < PlaneNum; j++)
00194     {
00195       if (plane_vector_[j].VecNum > plane_vector_[pmax].VecNum)
00196       {
00197         pmax = j;
00198       }
00199     }
00200     if (pmax != i)
00201       std::swap (plane_vector_[i], plane_vector_[pmax]);
00202   }
00203 /*
00204 for(int i = 0; i<PlaneNum; i++)
00205 {
00206         cout<< plane_vector_[i].VecNum<< "  ";
00207         if((i+1)%20 == 0) cout<<endl;
00208 }*/
00209 
00210 
00211   int iterate = 2;
00212   while (iterate-- > 1)
00213   {
00214     //concolidate planes
00215     int cnt = 0;
00216     vector < Plane > Planes;    //save the big plane
00217     vector < Plane > ExcludePlane;
00218     for (int i = 0; i < (int) plane_vector_.size (); i++)
00219     {
00220       cnt++;
00221       if (plane_vector_[i].VecNum < 4)
00222         break;
00223       // calculate the plane equation
00224       plane_vector_[i].A = plane_vector_[i].VecAve.x;
00225       plane_vector_[i].B = plane_vector_[i].VecAve.y;
00226       plane_vector_[i].C = plane_vector_[i].VecAve.z;
00227       plane_vector_[i].D = -(plane_vector_[i].A * plane_vector_[i].MeanVal.x 
00228                            + plane_vector_[i].B * plane_vector_[i].MeanVal.y 
00229                            + plane_vector_[i].C * plane_vector_[i].MeanVal.z);
00230       // consolidate planes to big planes
00231       bool flag = false;
00232       float angle;
00233       for (int j = 0; j < (int) Planes.size (); j++)
00234       {
00235         angle = srAngle (plane_vector_[i].VecAve, Planes[j].VecAve);
00236         angle = angle < (PI - angle) ? angle : (PI - angle);
00237         if (angle < 20 * PI / 180)
00238         {
00239           if (srP2Pl (plane_vector_[i].MeanVal, Planes[j]) < 0.1)
00240           {
00241             Planes[j].VecNum += plane_vector_[i].VecNum;
00242 
00243             //calculate the sum of normals
00244             Planes[j].VecSum += plane_vector_[i].VecSum;
00245 
00246             // calculate the normals
00247             Planes[j].VecAve.x = Planes[j].VecSum.x / Planes[j].VecNum;
00248             Planes[j].VecAve.y = Planes[j].VecSum.y / Planes[j].VecNum;
00249             Planes[j].VecAve.z = Planes[j].VecSum.z / Planes[j].VecNum;
00250 
00251             // calculate the sum of barycenters
00252             Planes[j].MeanSum += plane_vector_[i].MeanSum;
00253 
00254             // calculate the sum of barycenters
00255             Planes[j].MeanVal.x = Planes[j].MeanSum.x / Planes[j].VecNum;
00256             Planes[j].MeanVal.y = Planes[j].MeanSum.y / Planes[j].VecNum;
00257             Planes[j].MeanVal.z = Planes[j].MeanSum.z / Planes[j].VecNum;
00258 
00259             Planes[j].A = Planes[j].VecAve.x;
00260             Planes[j].B = Planes[j].VecAve.y;
00261             Planes[j].C = Planes[j].VecAve.z;
00262             Planes[j].D = -(Planes[j].A * Planes[j].MeanVal.x 
00263                           + Planes[j].B * Planes[j].MeanVal.y 
00264                           + Planes[j].C * Planes[j].MeanVal.z);
00265 
00266             int I = (int) plane_vector_[i].InnerPoints.size ();
00267             for (int k = 0; k < I; k++)
00268             {
00269               Planes[j].InnerPoints.push_back (plane_vector_[i].InnerPoints[k]);
00270             }
00271             flag = true;
00272             break;
00273           }
00274 
00275         }
00276       }
00277       // if any plane don't recruit this small plane
00278       if (!flag)
00279       {
00280         if ((int) Planes.size () < iterate * iterate * MAX_PLANE_NUM)
00281         {
00282           Plane ptemp;
00283           Planes.push_back (ptemp);
00284           std::swap (Planes[Planes.size () - 1], plane_vector_[i]);
00285         }
00286         else
00287         {
00288           Plane ptemp;
00289           ExcludePlane.push_back (ptemp);
00290           std::swap (ExcludePlane[ExcludePlane.size () - 1], plane_vector_[i]);
00291         }
00292       }
00293     }
00294     plane_vector_.swap (Planes);        //save the planes in the vector,and the first element is the biggest plane.
00295   }
00296   //find the boundary of every plane
00297   boundary_vec_.resize (plane_vector_.size ());
00298   for (int i = 0; i < (int) plane_vector_.size (); i++)
00299   {
00300     int flag = 0;
00301     boundary_vec_[i].push_back (plane_vector_[i].InnerPoints[0]);
00302     for (int j = 1; j < (int) plane_vector_[i].InnerPoints.size (); j++)
00303     {
00304       flag = 1;
00305       if (plane_vector_[i].InnerPoints[j - 1].i == plane_vector_[i].InnerPoints[j].i
00306           && plane_vector_[i].InnerPoints[j - 1].j + 1 == plane_vector_[i].InnerPoints[j].j)
00307         continue;
00308       else
00309       {
00310         boundary_vec_[i].push_back (plane_vector_[i].InnerPoints[j - 1]);
00311         boundary_vec_[i].push_back (plane_vector_[i].InnerPoints[j]);
00312         flag = 0;
00313       }
00314     }
00315     if (flag == 1)
00316       boundary_vec_[i].push_back (plane_vector_[i].InnerPoints.back ());
00317   }
00318 
00319   /*for(int i = 0; i<plane_vector_.size(); i++)
00320      {
00321      cout<< plane_vector_[i].InnerPoints.size()<< " --> "<< boundary_vec_[i].size()<< endl;
00322      } */
00323 
00324   // calculate the convex hull of every plane
00325   convex_vec_.resize (boundary_vec_.size ());
00326   for (int i = 0; i < (int) boundary_vec_.size (); i++)
00327   {
00328     int minidx = 0;
00329     for (int j = 1; j < (int) boundary_vec_[i].size (); j++)
00330     {
00331       if (boundary_vec_[i][j].i < boundary_vec_[i][minidx].i
00332           || (boundary_vec_[i][j].i == boundary_vec_[i][minidx].i
00333           && boundary_vec_[i][j].j < boundary_vec_[i][minidx].j))
00334         minidx = j;
00335     }
00336     if (minidx != 0)
00337       std::swap (boundary_vec_[i][0], boundary_vec_[i][minidx]);
00338 
00339     for (int j = 1; j < (int) boundary_vec_[i].size () - 1; j++)
00340     {
00341       int r = j;
00342       for (int k = j + 1; k < (int) boundary_vec_[i].size (); k++)
00343       {
00344         bool res = srCompL1R0bool (boundary_vec_[i][0], boundary_vec_[i][r], boundary_vec_[i][k]);
00345         if (res == 0)
00346           r = k;
00347       }
00348       if (r != j)
00349         std::swap (boundary_vec_[i][j], boundary_vec_[i][r]);
00350     }
00351 
00352     std::vector < CPointIndex > stack;
00353     stack.clear ();
00354     stack.push_back (boundary_vec_[i][0]);
00355     stack.push_back (boundary_vec_[i][1]);
00356     stack.push_back (boundary_vec_[i][2]);
00357 
00358     int top = 2;
00359     for (int j = 3; j < (int) boundary_vec_[i].size (); j++)
00360     {
00361       while (top >= 2 && srCross_Product (stack[top - 1], stack[top], boundary_vec_[i][j]) <= 0)
00362       {
00363         stack.pop_back ();
00364         top--;
00365       }
00366       stack.push_back (boundary_vec_[i][j]);
00367       top++;
00368     }
00369     convex_vec_[i].swap (stack);
00370   }
00371   /*
00372      for(int i = 0; i<boundary_vec_.size(); i++)
00373      {
00374      cout<< boundary_vec_[i].size() << " --> "<< boundary_vec_[i].size() << endl;
00375      }
00376    */
00377   plane_parameters_[0] = plane_vector_[0].A;
00378   plane_parameters_[1] = plane_vector_[0].B;
00379   plane_parameters_[2] = plane_vector_[0].C;
00380   plane_parameters_[3] = plane_vector_[0].D;
00381   //printf("%f,%f,%f,%f\n",planeparameters[0],planeparameters[1],planeparameters[2],planeparameters[3]);
00382 
00383   /*ofstream w("plane.txt");
00384      if (w.is_open())
00385      {
00386      printf("open the file ok\n");
00387      }
00388      else
00389      {
00390      printf("open the file fail\n");
00391      return 0 ;
00392      }
00393      for (int i = 0; i < plane_vector_[0].InnerPoints.size();i++)
00394      {
00395      int x = plane_vector_[0].InnerPoints[i].i;
00396      int y = plane_vector_[0].InnerPoints[i].j;
00397      w<<laser_data_[x][y].x<<"  "<<laser_data_[x][y].y<<"  "<<laser_data_[x][y].z<<"\n";
00398      }
00399      w.close(); */
00400 
00401   //return plane_parameters_;
00402 
00403 }
00404 
00405 float CSceneRecog::srPtopDistan (CPoint3d p1, CPoint3d p2)
00406 {
00407   return ((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z));
00408 }
00409 
00410 bool CSceneRecog::srIsAPlane (CPoint3d p[][DIMEN], CPoint3d m)
00411 {
00412   CPoint3d Pzero (0, 0, 0);
00413   int n = 3, jt = 100;
00414   float cov[9] = { 0.0 };
00415   float s1, s2, s3, min;
00416   float eps = 0.01f;
00417   CPoint3d sum, ptemp;
00418   int zeronum = 0;
00419   bool booldis = true;
00420   float distemp, maxdis = 0.0;
00421 
00422   ptemp = p[0][0];
00423   for (int i = 0; i < DIMEN; i++)
00424   {
00425     for (int j = 1; j < DIMEN; j++)
00426     {
00427       if (Pzero == p[i][j])
00428       {
00429         zeronum++;
00430       }
00431       else
00432       {
00433         distemp = srPtopDistan (ptemp, p[i][j]);
00434         if (distemp > maxdis)
00435         {
00436           maxdis = distemp;
00437         }
00438         ptemp = p[i][j];
00439       }
00440     }
00441   }
00442 
00443   if (maxdis > MAXDISTH1 * MAXDISTH1)   // || zeronum>DIMEN                
00444   {
00445     booldis = false;
00446     return false;
00447   }
00448   for (int i = 0; i < DIMEN; i++)
00449   {
00450     for (int j = 0; j < DIMEN; j++)
00451     {
00452       float buf[3];
00453       buf[0] = p[i][j].x - m.x;
00454       buf[1] = p[i][j].y - m.y;
00455       buf[2] = p[i][j].z - m.z;
00456       for (int k = 0; k < 3; k++)
00457         for (int l = 0; l < 3; l++)
00458           if (!(p[i][j] == Pzero))
00459           {
00460             cov[k * 3 + l] += buf[k] * buf[l];
00461           }
00462     }
00463   }
00464   // calculate the covariance matrice eigenvalue
00465   srEigenValue (cov, n, eps, jt);
00466   s1 = fabs (cov[0]);
00467   s2 = fabs (cov[4]);
00468   s3 = fabs (cov[8]);
00469   min = s1 < s2 ? s1 : s2;
00470   min = s3 < min ? s3 : min;
00471 
00472   //compare the minimum of eigenvalue with threshold
00473   if (min < THRESH && zeronum < DIMEN && booldis)
00474     return true;
00475   return false;
00476 }
00477 
00478 int CSceneRecog::srEigenValue (float a[], int n, double eps, int jt)
00479 {
00480   int i, j, u, w, t, s, l;
00481   int p = 0;
00482   int q = 0;
00483   float fm, cn, sn, omega, x, y, d, v[30];
00484   l = 1;
00485   for (i = 0; i <= n - 1; i++)
00486   {
00487     v[i * n + i] = 1.0;
00488     for (j = 0; j <= n - 1; j++)
00489     {
00490       if (i != j)
00491       {
00492         v[i * n + j] = 0.0;
00493       }
00494     }
00495   }
00496   while (l == 1)
00497   {
00498     fm = 0.0;
00499     for (i = 0; i <= n - 1; i++)
00500     {
00501       for (j = 0; j <= n - 1; j++)
00502       {
00503         d = fabs (a[i * n + j]);
00504         if ((i != j) && (d > fm))
00505         {
00506           fm = d;
00507           p = i;
00508           q = j;
00509         }
00510       }
00511     }
00512     if (fm < eps)
00513     {
00514       return (1);
00515     }
00516     if (l > jt)
00517     {
00518       return (-1);
00519     }
00520     l = l + 1;
00521     u = p * n + q;
00522     w = p * n + p;
00523     t = q * n + p;
00524     s = q * n + q;
00525     x = -a[u];
00526     y = (a[s] - a[w]) / 2.0;
00527     omega = x / sqrt (x * x + y * y);
00528     if (y < 0.0)
00529     {
00530       omega = -omega;
00531     }
00532     sn = 1.0 + sqrt (1.0 - omega * omega);
00533     sn = omega / sqrt (2.0 * sn);
00534     cn = sqrt (1.0 - sn * sn);
00535     fm = a[w];
00536     a[w] = fm * cn * cn + a[s] * sn * sn + a[u] * omega;
00537     a[s] = fm * sn * sn + a[s] * cn * cn - a[u] * omega;
00538     a[u] = 0.0;
00539     a[t] = 0.0;
00540     for (j = 0; j <= n - 1; j++)
00541     {
00542       if ((j != p) && (j != q))
00543       {
00544         u = p * n + j;
00545         w = q * n + j;
00546         fm = a[u];
00547         a[u] = fm * cn + a[w] * sn;
00548         a[w] = -fm * sn + a[w] * cn;
00549       }
00550     }
00551     for (i = 0; i <= n - 1; i++)
00552     {
00553       if ((i != p) && (i != q))
00554       {
00555         u = i * n + p;
00556         w = i * n + q;
00557         fm = a[u];
00558         a[u] = fm * cn + a[w] * sn;
00559         a[w] = -fm * sn + a[w] * cn;
00560       }
00561     }
00562     for (i = 0; i <= n - 1; i++)
00563     {
00564       u = i * n + p;
00565       w = i * n + q;
00566       fm = v[u];
00567       v[u] = fm * cn + v[w] * sn;
00568       v[w] = -fm * sn + v[w] * cn;
00569     }
00570   }
00571   return 0;
00572 }
00573 
00574 CPoint3d CSceneRecog::srNormalVec (CPoint3d start1, CPoint3d end1, CPoint3d start2, CPoint3d end2)
00575 {
00576   float r1, r2;
00577   CPoint3d point1, point2, point;
00578   point1 = srVecMuti (start1, end1, start1, end2);
00579   point2 = srVecMuti (start2, end1, start2, end2);
00580   r1 = sqrt (point1.x * point1.x + point1.y * point1.y + point1.z * point1.z);
00581   r2 = sqrt (point2.x * point2.x + point2.y * point2.y + point2.z * point2.z);
00582   point.x = (point1.x / r1 + point2.x / r2) / 2;
00583   point.y = (point1.y / r1 + point2.y / r2) / 2;
00584   point.z = (point1.z / r1 + point2.z / r2) / 2;
00585   return point;
00586 }
00587 
00588 CPoint3d CSceneRecog::srVecMuti (CPoint3d start1, CPoint3d end1, CPoint3d start2, CPoint3d end2)
00589 {
00590   float x1, y1, z1;
00591   float x2, y2, z2;
00592   x1 = end1.x - start1.x;
00593   y1 = end1.y - start1.y;
00594   z1 = end1.z - start1.z;
00595   x2 = end2.x - start2.x;
00596   y2 = end2.y - start2.y;
00597   z2 = end2.z - start2.z;
00598   CPoint3d point;
00599   point.x = y1 * z2 - y2 * z1;
00600   point.y = x2 * z1 - x1 * z2;
00601   point.z = x1 * y2 - x2 * y1;
00602   
00603   return point;
00604 }
00605 
00606 float CSceneRecog::srAngle (CPoint3d vec1, CPoint3d vec2)
00607 {
00608   float x1, y1, z1, p1, p2, /*r1,r2, */ result, theta;
00609   x1 = vec1.x * vec2.x;
00610   y1 = vec1.y * vec2.y;
00611   z1 = vec1.z * vec2.z;
00612   p1 = vec1.x * vec1.x + vec1.y * vec1.y + vec1.z * vec1.z;
00613   p2 = vec2.x * vec2.x + vec2.y * vec2.y + vec2.z * vec2.z;
00614   result = (x1 + y1 + z1) / sqrt (p1 * p2);
00615   theta = acos (result);
00616   
00617   return theta;
00618 }
00619 
00620 float CSceneRecog::srP2Pl (CPoint3d m, const Plane & Plane)
00621 {
00622   float dist;
00623   dist = fabs (Plane.A * m.x + Plane.B * m.y + Plane.C * m.z + Plane.D);
00624   dist = dist / sqrt (Plane.A * Plane.A + Plane.B * Plane.B + Plane.C * Plane.C);
00625   
00626   return dist;
00627 }
00628 
00629 void CSceneRecog::srCalColor (int idx, std::vector < float >&rgb)
00630 {
00631   static int preidx = 1000;
00632   float step = 1;
00633   if (idx < 0)
00634   {
00635     rgb[0] = 0.5;
00636     rgb[1] = 0.5;
00637     rgb[2] = 0.5;
00638   }
00639   else if (idx != preidx)
00640   {
00641     float ratio = idx % 8;
00642     ratio = (1 - ratio / 8);
00643     switch (idx % 6)
00644     {
00645       case 0:
00646         rgb[0] = ratio * step;
00647         rgb[1] = 0;
00648         rgb[2] = 0;
00649         break;
00650       case 1:
00651         rgb[0] = 0;
00652         rgb[1] = ratio * step;
00653         rgb[2] = 0;
00654         break;
00655       case 2:
00656         rgb[0] = 0;
00657         rgb[1] = 0;
00658         rgb[2] = ratio * step;
00659         break;
00660       case 3:
00661         rgb[0] = ratio * step;
00662         rgb[1] = ratio * step;
00663         rgb[2] = 0;
00664         break;
00665       case 4:
00666         rgb[0] = ratio * step;
00667         rgb[1] = 0;
00668         rgb[2] = ratio * step;
00669         break;
00670       case 5:
00671         rgb[0] = 0;
00672         rgb[1] = ratio * step;
00673         rgb[2] = ratio * step;
00674         break;
00675     }
00676   }
00677   preidx = idx;
00678 }
00679 
00680 bool CSceneRecog::srCompL1R0bool (const CPointIndex & p1, const CPointIndex & p2, const CPointIndex & p3)
00681 {
00682   bool res = 1;
00683   int temp = (p2.j - p1.j) * (p3.i - p1.i) - (p2.i - p1.i) * (p3.j - p1.j);
00684   if (temp < 0)
00685   {
00686     res = 0;
00687   }
00688   else if (temp == 0)
00689   {
00690     int dist1 = (p2.i - p1.i) * (p2.i - p1.i) + (p2.j - p1.j) * (p2.j - p1.j);
00691     int dist2 = (p3.i - p1.i) * (p3.i - p1.i) + (p3.j - p1.j) * (p3.j - p1.j);
00692     if (dist1 > dist2)
00693       res = 0;
00694   }
00695   
00696   return res;
00697 }
00698 
00699 inline int CSceneRecog::srCross_Product (const CPointIndex & p1, const CPointIndex & p2, const CPointIndex & p3)
00700 {
00701   return (p2.j - p1.j) * (p3.i - p1.i) - (p2.i - p1.i) * (p3.j - p1.j);
00702 }


camera_laser_calibration
Author(s): Zhao Cilang,Yan Fei,Zhuang Yan/zhuang@dlut.edu.cn
autogenerated on Sun Jan 5 2014 11:05:02