Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef DEPTH_IMAGE_TO_LASERSCAN
00035 #define DEPTH_IMAGE_TO_LASERSCAN
00036
00037 #include <sensor_msgs/Image.h>
00038 #include <sensor_msgs/LaserScan.h>
00039 #include <sensor_msgs/image_encodings.h>
00040 #include <image_geometry/pinhole_camera_model.h>
00041 #include <depthimage_to_laserscan/depth_traits.h>
00042 #include <sstream>
00043 #include <limits.h>
00044 #include <math.h>
00045
00046 namespace depthimage_to_laserscan
00047 {
00048 class DepthImageToLaserScan
00049 {
00050 public:
00051 DepthImageToLaserScan();
00052 ~DepthImageToLaserScan();
00053
00066 sensor_msgs::LaserScanPtr convert_msg(const sensor_msgs::ImageConstPtr& depth_msg,
00067 const sensor_msgs::CameraInfoConstPtr& info_msg);
00068
00079 void set_scan_time(const float scan_time);
00080
00091 void set_range_limits(const float range_min, const float range_max);
00092
00103 void set_scan_height(const int scan_height);
00104
00114 void set_output_frame(const std::string output_frame_id);
00115
00116 private:
00126 double magnitude_of_ray(const cv::Point3d& ray) const;
00127
00139 double angle_between_rays(const cv::Point3d& ray1, const cv::Point3d& ray2) const;
00140
00154 bool use_point(const float new_value, const float old_value, const float range_min, const float range_max) const;
00155
00169 template<typename T>
00170 void convert(const sensor_msgs::ImageConstPtr& depth_msg, const image_geometry::PinholeCameraModel& cam_model,
00171 const sensor_msgs::LaserScanPtr& scan_msg, const int& scan_height) const{
00172
00173 float center_x = cam_model.cx();
00174 float center_y = cam_model.cy();
00175
00176
00177 double unit_scaling = depthimage_to_laserscan::DepthTraits<T>::toMeters( T(1) );
00178 float constant_x = unit_scaling / cam_model.fx();
00179 float constant_y = unit_scaling / cam_model.fy();
00180
00181 const T* depth_row = reinterpret_cast<const T*>(&depth_msg->data[0]);
00182 int row_step = depth_msg->step / sizeof(T);
00183
00184 int offset = (int)(cam_model.cy()-scan_height/2);
00185 depth_row += offset*row_step;
00186
00187 for(int v = offset; v < offset+scan_height_; v++, depth_row += row_step){
00188 for (int u = 0; u < (int)depth_msg->width; u++)
00189 {
00190 T depth = depth_row[u];
00191
00192 double r = depth;
00193 double th = -atan2((double)(u - center_x) * constant_x, unit_scaling);
00194 int index = (th - scan_msg->angle_min) / scan_msg->angle_increment;
00195
00196 if (depthimage_to_laserscan::DepthTraits<T>::valid(depth)){
00197
00198 double x = (u - center_x) * depth * constant_x;
00199 double y = (v - center_y) * depth * constant_y;
00200 double z = depthimage_to_laserscan::DepthTraits<T>::toMeters(depth);
00201
00202
00203 r = sqrt(pow(x, 2.0) + pow(y, 2.0) + pow(z, 2.0));
00204 }
00205
00206
00207 if(use_point(r, scan_msg->ranges[index], scan_msg->range_min, scan_msg->range_max)){
00208 scan_msg->ranges[index] = r;
00209 }
00210 }
00211 }
00212 }
00213
00214 image_geometry::PinholeCameraModel cam_model_;
00215
00216 float scan_time_;
00217 float range_min_;
00218 float range_max_;
00219 int scan_height_;
00220 std::string output_frame_id_;
00221 };
00222
00223
00224 };
00225
00226 #endif