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
00040 #ifndef PCL_RANGE_IMAGE_H_
00041 #define PCL_RANGE_IMAGE_H_
00042
00043 #include <pcl/point_cloud.h>
00044 #include "pcl/pcl_macros.h"
00045 #include "pcl/point_types.h"
00046 #include "pcl/common/common_headers.h"
00047 #include <Eigen/Core>
00048 #include <Eigen/Geometry>
00049 #include <pcl/common/vector_average.h>
00050 #include <typeinfo>
00051
00052
00053 namespace pcl
00054 {
00055
00060 class RangeImage : public pcl::PointCloud<PointWithRange>
00061 {
00062 public:
00063
00064 typedef pcl::PointCloud<PointWithRange> BaseClass;
00065 typedef std::vector<Eigen::Vector3f, Eigen::aligned_allocator<Eigen::Vector3f> > VectorOfEigenVector3f;
00066
00067 enum CoordinateFrame
00068 {
00069 CAMERA_FRAME = 0,
00070 LASER_FRAME = 1
00071 };
00072
00073
00075 RangeImage ();
00077 ~RangeImage ();
00078
00079
00086 static inline float
00087 getMaxAngleSize (const Eigen::Affine3f& viewer_pose, const Eigen::Vector3f& center,
00088 float radius);
00089
00094 static inline Eigen::Vector3f
00095 getEigenVector3f (const PointWithRange& point);
00096
00101 static void
00102 getCoordinateFrameTransformation (RangeImage::CoordinateFrame coordinate_frame,
00103 Eigen::Affine3f& transformation);
00104
00110 template <typename PointCloudTypeWithViewpoints>
00111 static Eigen::Vector3f
00112 getAverageViewPoint (const PointCloudTypeWithViewpoints& point_cloud);
00113
00118 static void
00119 extractFarRanges (const sensor_msgs::PointCloud2& point_cloud_data, PointCloud<PointWithViewpoint>& far_ranges);
00120
00121
00123 void reset ();
00124
00138 template <typename PointCloudType>
00139 void
00140 createFromPointCloud (const PointCloudType& point_cloud, float angular_resolution, float max_angle_width,
00141 float max_angle_height, const Eigen::Affine3f& sensor_pose,
00142 CoordinateFrame coordinate_frame=CAMERA_FRAME, float noise_level=0.0f,
00143 float min_range=0.0f, int border_size=0);
00144
00159 template <typename PointCloudType>
00160 void
00161 createFromPointCloudWithKnownSize (const PointCloudType& point_cloud, float angular_resolution,
00162 const Eigen::Vector3f& point_cloud_center, float point_cloud_radius,
00163 const Eigen::Affine3f& sensor_pose,
00164 CoordinateFrame coordinate_frame=CAMERA_FRAME,
00165 float noise_level=0.0f, float min_range=0.0f, int border_size=0);
00166
00182 template <typename PointCloudTypeWithViewpoints>
00183 void
00184 createFromPointCloudWithViewpoints (const PointCloudTypeWithViewpoints& point_cloud, float angular_resolution,
00185 float max_angle_width, float max_angle_height,
00186 CoordinateFrame coordinate_frame=CAMERA_FRAME, float noise_level=0.0f,
00187 float min_range=0.0f, int border_size=0);
00188
00189 void
00190 integrateFarRanges (const PointCloud<PointWithViewpoint>& far_ranges);
00191
00199 void
00200 cropImage (int border_size=0, int top=-1, int right=-1, int bottom=-1, int left=-1);
00201
00206 float*
00207 getRangesArray () const;
00208
00211 inline const Eigen::Affine3f&
00212 getTransformationToRangeImageSystem () const { return to_range_image_system_;}
00213
00216 inline const Eigen::Affine3f&
00217 getTransformationToWorldSystem () const { return to_world_system_;}
00218
00220 inline float
00221 getAngularResolution () const { return angular_resolution_;}
00222
00226 inline void
00227 setAngularResolution (float angular_resolution);
00228
00234 inline const PointWithRange&
00235 getPoint (int image_x, int image_y) const;
00236
00238 inline PointWithRange&
00239 getPoint (int image_x, int image_y);
00240
00242 inline const PointWithRange&
00243 getPoint (float image_x, float image_y) const;
00245 inline PointWithRange&
00246 getPoint (float image_x, float image_y);
00247
00254 inline const PointWithRange&
00255 getPointNoCheck (int image_x, int image_y) const;
00256
00258 inline PointWithRange&
00259 getPointNoCheck (int image_x, int image_y);
00260
00262 inline void
00263 getPoint (int image_x, int image_y, Eigen::Vector3f& point) const;
00264
00266 inline void
00267 getPoint (int index, Eigen::Vector3f& point) const;
00268
00270 inline const Eigen::Map<const Eigen::Vector3f>
00271 getEigenVector3f (int x, int y) const;
00272
00274 inline const Eigen::Map<const Eigen::Vector3f>
00275 getEigenVector3f (int index) const;
00276
00278 inline const PointWithRange&
00279 getPoint (int index) const;
00280
00287 inline const PointWithRange&
00288 getPointConsideringWrapAround (int image_x, int image_y) const;
00289
00291 inline void
00292 calculate3DPoint (float image_x, float image_y, float range, PointWithRange& point) const;
00294 inline void
00295 calculate3DPoint (float image_x, float image_y, PointWithRange& point) const;
00296
00298 virtual inline void
00299 calculate3DPoint (float image_x, float image_y, float range, Eigen::Vector3f& point) const;
00301 inline void
00302 calculate3DPoint (float image_x, float image_y, Eigen::Vector3f& point) const;
00303
00305 void
00306 recalculate3DPointPositions ();
00307
00309 inline virtual void
00310 getImagePoint (const Eigen::Vector3f& point, float& image_x, float& image_y, float& range) const;
00311
00313 inline void
00314 getImagePoint (const Eigen::Vector3f& point, int& image_x, int& image_y, float& range) const;
00315
00317 inline void
00318 getImagePoint (const Eigen::Vector3f& point, float& image_x, float& image_y) const;
00319
00321 inline void
00322 getImagePoint (const Eigen::Vector3f& point, int& image_x, int& image_y) const;
00323
00325 inline void
00326 getImagePoint (float x, float y, float z, float& image_x, float& image_y, float& range) const;
00327
00329 inline void
00330 getImagePoint (float x, float y, float z, float& image_x, float& image_y) const;
00331
00333 inline void
00334 getImagePoint (float x, float y, float z, int& image_x, int& image_y) const;
00335
00338 inline float
00339 checkPoint (const Eigen::Vector3f& point, PointWithRange& point_in_image) const;
00340
00344 inline float
00345 getRangeDifference (const Eigen::Vector3f& point) const;
00346
00348 inline void
00349 getImagePointFromAngles (float angle_x, float angle_y, float& image_x, float& image_y) const;
00350
00352 inline void
00353 getAnglesFromImagePoint (float image_x, float image_y, float& angle_x, float& angle_y) const;
00354
00356 inline void
00357 real2DToInt2D (float x, float y, int& xInt, int& yInt) const;
00358
00360 inline bool
00361 isInImage (int x, int y) const;
00362
00364 inline bool
00365 isValid (int x, int y) const;
00366
00368 inline bool
00369 isValid (int index) const;
00370
00372 inline bool
00373 isObserved (int x, int y) const;
00374
00376 inline bool
00377 isMaxRange (int x, int y) const;
00378
00382 inline bool
00383 getNormal (int x, int y, int radius, Eigen::Vector3f& normal, int step_size=1) const;
00384
00386 inline bool
00387 getNormalForClosestNeighbors (int x, int y, int radius, const PointWithRange& point,
00388 int no_of_nearest_neighbors, Eigen::Vector3f& normal, int step_size=1) const;
00389
00391 inline bool
00392 getNormalForClosestNeighbors (int x, int y, int radius, const Eigen::Vector3f& point,
00393 int no_of_nearest_neighbors, Eigen::Vector3f& normal,
00394 Eigen::Vector3f* point_on_plane=NULL, int step_size=1) const;
00395
00397 inline bool
00398 getNormalForClosestNeighbors (int x, int y, Eigen::Vector3f& normal, int radius=2) const;
00399
00402 inline bool
00403 getSurfaceInformation (int x, int y, int radius, const Eigen::Vector3f& point,
00404 int no_of_closest_neighbors, int step_size,
00405 float& max_closest_neighbor_distance_squared,
00406 Eigen::Vector3f& normal, Eigen::Vector3f& mean, Eigen::Vector3f& eigen_values,
00407 Eigen::Vector3f* normal_all_neighbors=NULL,
00408 Eigen::Vector3f* mean_all_neighbors=NULL,
00409 Eigen::Vector3f* eigen_values_all_neighbors=NULL) const;
00410
00411
00412 inline float
00413 getSquaredDistanceOfNthNeighbor (int x, int y, int radius, int n, int step_size) const;
00414
00417 inline float
00418 getImpactAngle (const PointWithRange& point1, const PointWithRange& point2) const;
00420 inline float
00421 getImpactAngle (int x1, int y1, int x2, int y2) const;
00422
00425 inline float
00426 getImpactAngleBasedOnLocalNormal (int x, int y, int radius) const;
00428 float*
00429 getImpactAngleImageBasedOnLocalNormals (int radius) const;
00430
00434 inline float
00435 getNormalBasedAcutenessValue (int x, int y, int radius) const;
00436
00439 inline float
00440 getAcutenessValue (const PointWithRange& point1, const PointWithRange& point2) const;
00442 inline float
00443 getAcutenessValue (int x1, int y1, int x2, int y2) const;
00444
00446 void
00447 getAcutenessValueImages (int pixel_distance, float*& acuteness_value_image_x,
00448 float*& acuteness_value_image_y) const;
00449
00452
00453
00454
00455
00457 float
00458 getSurfaceChange (int x, int y, int radius) const;
00459
00461 float*
00462 getSurfaceChangeImage (int radius) const;
00463
00466 inline void
00467 getSurfaceAngleChange (int x, int y, int radius, float& angle_change_x, float& angle_change_y) const;
00468
00470 void
00471 getSurfaceAngleChangeImages (int radius, float*& angle_change_image_x, float*& angle_change_image_y) const;
00472
00474 inline float
00475 getCurvature (int x, int y, int radius, int step_size) const;
00476
00478 inline const Eigen::Vector3f
00479 getSensorPos () const;
00480
00482 void
00483 setUnseenToMaxRange ();
00484
00486 int
00487 getImageOffsetX () const { return image_offset_x_;}
00489 int
00490 getImageOffsetY () const { return image_offset_y_;}
00491
00505 virtual void
00506 getSubImage (int sub_image_image_offset_x, int sub_image_image_offset_y, int sub_image_width,
00507 int sub_image_height, int combine_pixels, RangeImage& sub_image) const;
00508
00510 virtual void
00511 getHalfImage(RangeImage& half_image) const;
00512
00514 void
00515 getMinMaxRanges (float& min_range, float& max_range) const;
00516
00518 void
00519 change3dPointsToLocalCoordinateFrame ();
00520
00525 float*
00526 getInterpolatedSurfaceProjection (const Eigen::Affine3f& pose, int pixel_size, float world_size) const;
00527
00529 float*
00530 getInterpolatedSurfaceProjection (const Eigen::Vector3f& point, int pixel_size, float world_size) const;
00531
00533 inline Eigen::Affine3f
00534 getTransformationToViewerCoordinateFrame (const Eigen::Vector3f& point) const;
00536 inline void
00537 getTransformationToViewerCoordinateFrame (const Eigen::Vector3f& point,
00538 Eigen::Affine3f& transformation) const;
00540 inline void
00541 getRotationToViewerCoordinateFrame (const Eigen::Vector3f& point, Eigen::Affine3f& transformation) const;
00542
00544 bool
00545 getNormalBasedUprightTransformation (const Eigen::Vector3f& point,
00546 float max_dist, Eigen::Affine3f& transformation) const;
00547
00550 void
00551 getIntegralImage (float*& integral_image, int*& valid_points_num_image) const;
00552
00554 void
00555 getBlurredImageUsingIntegralImage (int blur_radius, float* integral_image, int* valid_points_num_image,
00556 RangeImage& range_image) const;
00557
00559 void
00560 getBlurredImage (int blur_radius, RangeImage& range_image) const;
00561
00564 inline float
00565 getEuclideanDistanceSquared (int x1, int y1, int x2, int y2) const;
00567 inline float
00568 getAverageEuclideanDistance (int x, int y, int offset_x, int offset_y, int max_steps) const;
00569
00571 void
00572 getRangeImageWithSmoothedSurface (int radius, RangeImage& smoothed_range_image) const;
00573
00574
00579 inline void
00580 get1dPointAverage (int x, int y, int delta_x, int delta_y, int no_of_points,
00581 PointWithRange& average_point) const;
00582
00584 Eigen::Affine3f
00585 doIcp (const VectorOfEigenVector3f& points,
00586 const Eigen::Affine3f& initial_guess, int search_radius,
00587 float max_distance_start, float max_distance_end, int num_iterations) const;
00588
00590 inline bool
00591 getViewingDirection (int x, int y, Eigen::Vector3f& viewing_direction) const;
00592
00594 inline void
00595 getViewingDirection (const Eigen::Vector3f& point, Eigen::Vector3f& viewing_direction) const;
00596
00599 virtual RangeImage* getNew() const { return new RangeImage; }
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 static bool debug;
00612 protected:
00613
00614 Eigen::Affine3f to_range_image_system_;
00615 Eigen::Affine3f to_world_system_;
00616 float angular_resolution_;
00617 float angular_resolution_reciprocal_;
00619 int image_offset_x_, image_offset_y_;
00621 PointWithRange unobserved_point;
00624
00625 template <typename PointCloudType>
00626 void
00627 doZBuffer (const PointCloudType& point_cloud, float noise_level,
00628 float min_range, int& top, int& right, int& bottom, int& left);
00629
00630 public:
00631 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00632 };
00633
00634 inline std::ostream&
00635 operator<< (std::ostream& os, const RangeImage& r)
00636 {
00637 os << "range image of size "<<r.width<<"x"<<r.height<<" with angular resolution "
00638 << RAD2DEG (r.getAngularResolution ()) << "deg/pixel and "<<r.points.size ()<<" points";
00639 return os;
00640 }
00641
00642 }
00643
00644
00645 #include "pcl/range_image/range_image.hpp"
00646
00647 #endif //#ifndef PCL_RANGE_IMAGE_H_