detect_laser_corners.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 //========================================================================================================
00034 //Here we provide a solution to detect the corners of laser data .
00035 //First,we select the points of chessboard acording the environment.
00036 //Second,we extract the chessboard plane,and caculate the distance between laser and chessboard.
00037 //Third,we detect the corners acording the distance.
00038 //========================================================================================================
00039 #include "ros/ros.h"
00040 #include "sensor_msgs/PointCloud.h"
00041 #include <pcl/io/pcd_io.h>
00042 #include <pcl/point_types.h>
00043 
00044 #include "camera_laser_calibration/scene_recog/scene_recog.h"
00045 #include "camera_laser_calibration/white_black_grid.h"
00046 
00047 #define L_MAX 3
00048 #define L_MIN 1
00049 #define Z_MAX 1.9
00050 #define Z_MIN -0.5
00051 
00052 int main (int argc, char **argv)
00053 {
00054   ros::init (argc, argv, "detect_laser_corners");
00055   char *file_name = argv[1];    //put int the name of pcd file
00056 
00057   pcl::PointCloud < pcl::PointXYZ >::Ptr cloud (new pcl::PointCloud < pcl::PointXYZ >);
00058 
00059   if (pcl::io::loadPCDFile < pcl::PointXYZ > (file_name, *cloud) == -1) // load the file
00060   {
00061     PCL_ERROR ("Couldn't read file \n");
00062     
00063     return (-1);
00064   }
00065   else
00066   {
00067     ROS_INFO ("Read file successfully");
00068     ROS_INFO ("points number = %d", cloud->width * cloud->height);
00069   }
00070 
00071   int n_width_raw = cloud->width;       //get the height of row cloud
00072   int n_height_raw = cloud->height;     //get the width of row cloud
00073 
00074   std::vector < BinIndex > vec_ij;
00075   BinIndex bin_ij;
00076   //detect the points of board from a point cloud according to the z value and distance between laser and board.And this is rough.
00077   for (int j = 0; j < n_height_raw; j++)
00078     for (int i = 0; i < n_width_raw; i++)
00079     {
00080       if ((cloud->points[j * n_width_raw + i].z < Z_MAX) && (cloud->points[j * n_width_raw + i].z > Z_MIN))
00081       {
00082         float x = cloud->points[j * n_width_raw + i].x;
00083         float y = cloud->points[j * n_width_raw + i].y;
00084         float z = cloud->points[j * n_width_raw + i].z;
00085         if ((sqrt (x * x + y * y + z * z) > L_MIN) && (sqrt (x * x + y * y + z * z) < L_MAX))
00086         {
00087           bin_ij.bin_i = i;
00088           bin_ij.bin_j = j;
00089           vec_ij.push_back (bin_ij);
00090         }
00091       }
00092     }
00093   size_t iMin = vec_ij[0].bin_i;
00094   size_t iMax = vec_ij[0].bin_i;
00095   for (int i = 1; i < (int) vec_ij.size (); i++)
00096   {
00097     if (vec_ij[i].bin_i > iMax)
00098     {
00099       iMax = vec_ij[i].bin_i;
00100     }
00101     if (vec_ij[i].bin_i < iMin)
00102     {
00103       iMin = vec_ij[i].bin_i;
00104     }
00105 
00106   }
00107   size_t jMin = vec_ij[0].bin_j + 5;
00108   size_t jMax = vec_ij[vec_ij.size () - 1].bin_j - 5;
00109 
00110   ROS_INFO ("iMin = %d\n", iMin);
00111   ROS_INFO ("iMax = %d\n", iMax);
00112   ROS_INFO ("jMin = %d\n", jMin);
00113   ROS_INFO ("jMax = %d\n", jMax);
00114 
00115   int n_width_choosed = iMax - iMin + 1;
00116   int n_height_choosed = jMax - jMin + 1;
00117 
00118   //find the points of board accurately
00119   std::vector < CPoint3d > vec_one_frame (n_width_choosed);
00120   std::vector < std::vector < CPoint3d > >vec_all_frame (n_height_choosed);
00121   for (unsigned int j = jMin, p = 0; j < jMax + 1; j++, p++)
00122   {
00123     for (unsigned int i = iMin, q = 0; i < iMax + 1; i++, q++)
00124     {
00125       vec_one_frame[q].x = cloud->points[j * 361 + i].x;
00126       vec_one_frame[q].y = cloud->points[j * 361 + i].y;
00127       vec_one_frame[q].z = cloud->points[j * 361 + i].z;
00128     }
00129     vec_all_frame[p] = vec_one_frame;
00130   }
00131   
00132   ROS_INFO ("n_width_choosed = %d\n", n_width_choosed);
00133   ROS_INFO ("n_height_choosed = %d\n", n_height_choosed);
00134 
00135   std::vector < std::vector < CPoint3d > >vec_cloud_raw;
00136   vec_cloud_raw = vec_all_frame;
00137   //extract the chessboard plane,and caculate the distance between laser and chessboard
00138   CSceneRecog scene_recog;
00139   scene_recog.srProcess (vec_all_frame);
00140   float plane_parameters[4];
00141   plane_parameters[0] =  scene_recog.plane_parameters_[0];
00142   plane_parameters[1] =  scene_recog.plane_parameters_[1];
00143   plane_parameters[2] =  scene_recog.plane_parameters_[2];
00144   plane_parameters[3] =  scene_recog.plane_parameters_[3];
00145 
00146   printf ("A = %f,B = %f,C = %f,D = %f\n", plane_parameters[0], plane_parameters[1], plane_parameters[2], plane_parameters[3]);
00147 
00148   //detect the chessboard cornersscene_recog.
00149   CWhiteBlackGrid whiteblack_grid;
00150   whiteblack_grid.whgNodeDetect (n_height_choosed, n_width_choosed, plane_parameters, vec_cloud_raw);
00151   whiteblack_grid.whgNodeModify ();
00152 
00153   return 0;
00154 }


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