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
00035
00036
00037
00038
00039
00040 #ifndef PCL_ORGANIZED_CONVERSION_H_
00041 #define PCL_ORGANIZED_CONVERSION_H_
00042
00043 #include <pcl/pcl_macros.h>
00044 #include <pcl/point_cloud.h>
00045
00046 #include <vector>
00047 #include <limits>
00048 #include <assert.h>
00049
00050 namespace pcl
00051 {
00052 namespace io
00053 {
00054
00055 template<typename PointT> struct CompressionPointTraits
00056 {
00057 static const bool hasColor = false;
00058 static const unsigned int channels = 1;
00059 static const size_t bytesPerPoint = 3 * sizeof(float);
00060 };
00061
00062 template<>
00063 struct CompressionPointTraits<PointXYZRGB>
00064 {
00065 static const bool hasColor = true;
00066 static const unsigned int channels = 4;
00067 static const size_t bytesPerPoint = 3 * sizeof(float) + 3 * sizeof(uint8_t);
00068 };
00069
00070 template<>
00071 struct CompressionPointTraits<PointXYZRGBA>
00072 {
00073 static const bool hasColor = true;
00074 static const unsigned int channels = 4;
00075 static const size_t bytesPerPoint = 3 * sizeof(float) + 3 * sizeof(uint8_t);
00076 };
00077
00079 template <typename PointT, bool enableColor = CompressionPointTraits<PointT>::hasColor >
00080 struct OrganizedConversion;
00081
00083
00085 template<typename PointT>
00086 struct OrganizedConversion<PointT, false>
00087 {
00096 static void convert(const pcl::PointCloud<PointT>& cloud_arg,
00097 float focalLength_arg,
00098 float disparityShift_arg,
00099 float disparityScale_arg,
00100 bool ,
00101 typename std::vector<uint16_t>& disparityData_arg,
00102 typename std::vector<uint8_t>&)
00103 {
00104 size_t cloud_size, i;
00105
00106 cloud_size = cloud_arg.points.size ();
00107
00108
00109 disparityData_arg.clear ();
00110
00111 disparityData_arg.reserve (cloud_size);
00112
00113 for (i = 0; i < cloud_size; ++i)
00114 {
00115
00116 const PointT& point = cloud_arg.points[i];
00117
00118 if (pcl::isFinite (point))
00119 {
00120
00121 uint16_t disparity = static_cast<uint16_t> ( focalLength_arg / (disparityScale_arg * point.z) + disparityShift_arg / disparityScale_arg);
00122 disparityData_arg.push_back (disparity);
00123 }
00124 else
00125 {
00126
00127 disparityData_arg.push_back (0);
00128 }
00129 }
00130 }
00131
00142 static void convert(typename std::vector<uint16_t>& disparityData_arg,
00143 typename std::vector<uint8_t>&,
00144 bool,
00145 size_t width_arg,
00146 size_t height_arg,
00147 float focalLength_arg,
00148 float disparityShift_arg,
00149 float disparityScale_arg,
00150 pcl::PointCloud<PointT>& cloud_arg)
00151 {
00152 size_t i;
00153 size_t cloud_size = width_arg * height_arg;
00154 int x, y, centerX, centerY;
00155
00156 assert(disparityData_arg.size()==cloud_size);
00157
00158
00159 cloud_arg.points.clear ();
00160 cloud_arg.points.reserve (cloud_size);
00161
00162
00163 cloud_arg.width = static_cast<uint32_t> (width_arg);
00164 cloud_arg.height = static_cast<uint32_t> (height_arg);
00165 cloud_arg.is_dense = false;
00166
00167
00168 centerX = static_cast<int> (width_arg / 2);
00169 centerY = static_cast<int> (height_arg / 2);
00170
00171 const float fl_const = 1.0f / focalLength_arg;
00172 static const float bad_point = std::numeric_limits<float>::quiet_NaN ();
00173
00174 i = 0;
00175 for (y = -centerY; y < +centerY; ++y)
00176 for (x = -centerX; x < +centerX; ++x)
00177 {
00178 PointT newPoint;
00179 const uint16_t& pixel_disparity = disparityData_arg[i];
00180 ++i;
00181
00182 if (pixel_disparity)
00183 {
00184
00185 float depth = focalLength_arg / (static_cast<float> (pixel_disparity) * disparityScale_arg + disparityShift_arg);
00186
00187
00188 newPoint.x = static_cast<float> (x) * depth * fl_const;
00189 newPoint.y = static_cast<float> (y) * depth * fl_const;
00190 newPoint.z = depth;
00191
00192 }
00193 else
00194 {
00195
00196 newPoint.x = newPoint.y = newPoint.z = bad_point;
00197 }
00198
00199 cloud_arg.points.push_back (newPoint);
00200 }
00201
00202 }
00203
00204
00213 static void convert(typename std::vector<float>& depthData_arg,
00214 typename std::vector<uint8_t>&,
00215 bool,
00216 size_t width_arg,
00217 size_t height_arg,
00218 float focalLength_arg,
00219 pcl::PointCloud<PointT>& cloud_arg)
00220 {
00221 size_t i;
00222 size_t cloud_size = width_arg * height_arg;
00223 int x, y, centerX, centerY;
00224
00225 assert(depthData_arg.size()==cloud_size);
00226
00227
00228 cloud_arg.points.clear ();
00229 cloud_arg.points.reserve (cloud_size);
00230
00231
00232 cloud_arg.width = static_cast<uint32_t> (width_arg);
00233 cloud_arg.height = static_cast<uint32_t> (height_arg);
00234 cloud_arg.is_dense = false;
00235
00236
00237 centerX = static_cast<int> (width_arg / 2);
00238 centerY = static_cast<int> (height_arg / 2);
00239
00240 const float fl_const = 1.0f / focalLength_arg;
00241 static const float bad_point = std::numeric_limits<float>::quiet_NaN ();
00242
00243 i = 0;
00244 for (y = -centerY; y < +centerY; ++y)
00245 for (x = -centerX; x < +centerX; ++x)
00246 {
00247 PointT newPoint;
00248 const float& pixel_depth = depthData_arg[i];
00249 ++i;
00250
00251 if (pixel_depth)
00252 {
00253
00254 float depth = focalLength_arg / pixel_depth;
00255
00256
00257 newPoint.x = static_cast<float> (x) * depth * fl_const;
00258 newPoint.y = static_cast<float> (y) * depth * fl_const;
00259 newPoint.z = depth;
00260
00261 }
00262 else
00263 {
00264
00265 newPoint.x = newPoint.y = newPoint.z = bad_point;
00266 }
00267
00268 cloud_arg.points.push_back (newPoint);
00269 }
00270
00271 }
00272
00273 };
00274
00276
00278 template <typename PointT>
00279 struct OrganizedConversion<PointT, true>
00280 {
00291 static void convert(const pcl::PointCloud<PointT>& cloud_arg,
00292 float focalLength_arg,
00293 float disparityShift_arg,
00294 float disparityScale_arg,
00295 bool convertToMono,
00296 typename std::vector<uint16_t>& disparityData_arg,
00297 typename std::vector<uint8_t>& rgbData_arg)
00298 {
00299 size_t cloud_size, i;
00300
00301 cloud_size = cloud_arg.points.size ();
00302
00303
00304 disparityData_arg.clear ();
00305 rgbData_arg.clear ();
00306
00307
00308 disparityData_arg.reserve (cloud_size);
00309 if (convertToMono)
00310 {
00311 rgbData_arg.reserve (cloud_size);
00312 } else
00313 {
00314 rgbData_arg.reserve (cloud_size * 3);
00315 }
00316
00317
00318 for (i = 0; i < cloud_size; ++i)
00319 {
00320 const PointT& point = cloud_arg.points[i];
00321
00322 if (pcl::isFinite (point))
00323 {
00324 if (convertToMono)
00325 {
00326
00327 const uint32_t rgb = *reinterpret_cast<const int*> (&point.rgb);
00328 uint8_t grayvalue = static_cast<uint8_t>(0.2989 * static_cast<float>((rgb >> 16) & 0x0000ff) +
00329 0.5870 * static_cast<float>((rgb >> 8) & 0x0000ff) +
00330 0.1140 * static_cast<float>((rgb >> 0) & 0x0000ff));
00331
00332 rgbData_arg.push_back (grayvalue);
00333 } else
00334 {
00335
00336 const uint32_t rgb = *reinterpret_cast<const int*> (&point.rgb);
00337
00338 rgbData_arg.push_back ( (rgb >> 16) & 0x0000ff);
00339 rgbData_arg.push_back ( (rgb >> 8) & 0x0000ff);
00340 rgbData_arg.push_back ( (rgb >> 0) & 0x0000ff);
00341 }
00342
00343
00344
00345 uint16_t disparity = static_cast<uint16_t> (focalLength_arg / (disparityScale_arg * point.z) + disparityShift_arg / disparityScale_arg);
00346
00347
00348 disparityData_arg.push_back (disparity);
00349 }
00350 else
00351 {
00352
00353
00354 if (convertToMono)
00355 {
00356 rgbData_arg.push_back (0);
00357 } else
00358 {
00359 rgbData_arg.push_back (0);
00360 rgbData_arg.push_back (0);
00361 rgbData_arg.push_back (0);
00362 }
00363
00364
00365 disparityData_arg.push_back (0);
00366 }
00367 }
00368
00369 }
00370
00383 static void convert(typename std::vector<uint16_t>& disparityData_arg,
00384 typename std::vector<uint8_t>& rgbData_arg,
00385 bool monoImage_arg,
00386 size_t width_arg,
00387 size_t height_arg,
00388 float focalLength_arg,
00389 float disparityShift_arg,
00390 float disparityScale_arg,
00391 pcl::PointCloud<PointT>& cloud_arg)
00392 {
00393 size_t i;
00394 size_t cloud_size = width_arg*height_arg;
00395 bool hasColor = (rgbData_arg.size () > 0);
00396
00397
00398 assert (disparityData_arg.size()==cloud_size);
00399 if (hasColor)
00400 {
00401 if (monoImage_arg)
00402 {
00403 assert (rgbData_arg.size()==cloud_size);
00404 } else
00405 {
00406 assert (rgbData_arg.size()==cloud_size*3);
00407 }
00408 }
00409
00410 int x, y, centerX, centerY;
00411
00412
00413 cloud_arg.points.clear();
00414 cloud_arg.points.reserve(cloud_size);
00415
00416
00417 cloud_arg.width = static_cast<uint32_t>(width_arg);
00418 cloud_arg.height = static_cast<uint32_t>(height_arg);
00419 cloud_arg.is_dense = false;
00420
00421
00422 centerX = static_cast<int>(width_arg/2);
00423 centerY = static_cast<int>(height_arg/2);
00424
00425 const float fl_const = 1.0f/focalLength_arg;
00426 static const float bad_point = std::numeric_limits<float>::quiet_NaN ();
00427
00428 i = 0;
00429 for (y=-centerY; y<+centerY; ++y )
00430 for (x=-centerX; x<+centerX; ++x )
00431 {
00432 PointT newPoint;
00433
00434 const uint16_t& pixel_disparity = disparityData_arg[i];
00435
00436 if (pixel_disparity && (pixel_disparity!=0x7FF))
00437 {
00438 float depth = focalLength_arg / (static_cast<float> (pixel_disparity) * disparityScale_arg + disparityShift_arg);
00439
00440
00441 newPoint.z = depth;
00442 newPoint.x = static_cast<float> (x) * depth * fl_const;
00443 newPoint.y = static_cast<float> (y) * depth * fl_const;
00444
00445 if (hasColor)
00446 {
00447 if (monoImage_arg)
00448 {
00449 const uint8_t& pixel_r = rgbData_arg[i];
00450 const uint8_t& pixel_g = rgbData_arg[i];
00451 const uint8_t& pixel_b = rgbData_arg[i];
00452
00453
00454 uint32_t rgb = (static_cast<uint32_t>(pixel_r) << 16
00455 | static_cast<uint32_t>(pixel_g) << 8
00456 | static_cast<uint32_t>(pixel_b));
00457 newPoint.rgb = *reinterpret_cast<float*>(&rgb);
00458 } else
00459 {
00460 const uint8_t& pixel_r = rgbData_arg[i*3+0];
00461 const uint8_t& pixel_g = rgbData_arg[i*3+1];
00462 const uint8_t& pixel_b = rgbData_arg[i*3+2];
00463
00464
00465 uint32_t rgb = (static_cast<uint32_t>(pixel_r) << 16
00466 | static_cast<uint32_t>(pixel_g) << 8
00467 | static_cast<uint32_t>(pixel_b));
00468 newPoint.rgb = *reinterpret_cast<float*>(&rgb);
00469 }
00470
00471 } else
00472 {
00473
00474 uint32_t rgb = (static_cast<uint32_t>(255) << 16
00475 | static_cast<uint32_t>(255) << 8
00476 | static_cast<uint32_t>(255));
00477 newPoint.rgb = *reinterpret_cast<float*>(&rgb);
00478 }
00479 } else
00480 {
00481
00482 newPoint.x = newPoint.y = newPoint.z = bad_point;
00483 newPoint.rgb = 0.0f;
00484 }
00485
00486
00487 cloud_arg.points.push_back(newPoint);
00488
00489 ++i;
00490 }
00491 }
00492
00503 static void convert(typename std::vector<float>& depthData_arg,
00504 typename std::vector<uint8_t>& rgbData_arg,
00505 bool monoImage_arg,
00506 size_t width_arg,
00507 size_t height_arg,
00508 float focalLength_arg,
00509 pcl::PointCloud<PointT>& cloud_arg)
00510 {
00511 size_t i;
00512 size_t cloud_size = width_arg*height_arg;
00513 bool hasColor = (rgbData_arg.size () > 0);
00514
00515
00516 assert (depthData_arg.size()==cloud_size);
00517 if (hasColor)
00518 {
00519 if (monoImage_arg)
00520 {
00521 assert (rgbData_arg.size()==cloud_size);
00522 } else
00523 {
00524 assert (rgbData_arg.size()==cloud_size*3);
00525 }
00526 }
00527
00528 int x, y, centerX, centerY;
00529
00530
00531 cloud_arg.points.clear();
00532 cloud_arg.points.reserve(cloud_size);
00533
00534
00535 cloud_arg.width = static_cast<uint32_t>(width_arg);
00536 cloud_arg.height = static_cast<uint32_t>(height_arg);
00537 cloud_arg.is_dense = false;
00538
00539
00540 centerX = static_cast<int>(width_arg/2);
00541 centerY = static_cast<int>(height_arg/2);
00542
00543 const float fl_const = 1.0f/focalLength_arg;
00544 static const float bad_point = std::numeric_limits<float>::quiet_NaN ();
00545
00546 i = 0;
00547 for (y=-centerY; y<+centerY; ++y )
00548 for (x=-centerX; x<+centerX; ++x )
00549 {
00550 PointT newPoint;
00551
00552 const float& pixel_depth = depthData_arg[i];
00553
00554 if (pixel_depth==pixel_depth)
00555 {
00556 float depth = focalLength_arg / pixel_depth;
00557
00558
00559 newPoint.z = depth;
00560 newPoint.x = static_cast<float> (x) * depth * fl_const;
00561 newPoint.y = static_cast<float> (y) * depth * fl_const;
00562
00563 if (hasColor)
00564 {
00565 if (monoImage_arg)
00566 {
00567 const uint8_t& pixel_r = rgbData_arg[i];
00568 const uint8_t& pixel_g = rgbData_arg[i];
00569 const uint8_t& pixel_b = rgbData_arg[i];
00570
00571
00572 uint32_t rgb = (static_cast<uint32_t>(pixel_r) << 16
00573 | static_cast<uint32_t>(pixel_g) << 8
00574 | static_cast<uint32_t>(pixel_b));
00575 newPoint.rgb = *reinterpret_cast<float*>(&rgb);
00576 } else
00577 {
00578 const uint8_t& pixel_r = rgbData_arg[i*3+0];
00579 const uint8_t& pixel_g = rgbData_arg[i*3+1];
00580 const uint8_t& pixel_b = rgbData_arg[i*3+2];
00581
00582
00583 uint32_t rgb = (static_cast<uint32_t>(pixel_r) << 16
00584 | static_cast<uint32_t>(pixel_g) << 8
00585 | static_cast<uint32_t>(pixel_b));
00586 newPoint.rgb = *reinterpret_cast<float*>(&rgb);
00587 }
00588
00589 } else
00590 {
00591
00592 uint32_t rgb = (static_cast<uint32_t>(255) << 16
00593 | static_cast<uint32_t>(255) << 8
00594 | static_cast<uint32_t>(255));
00595 newPoint.rgb = *reinterpret_cast<float*>(&rgb);
00596 }
00597 } else
00598 {
00599
00600 newPoint.x = newPoint.y = newPoint.z = bad_point;
00601 newPoint.rgb = 0.0f;
00602 }
00603
00604
00605 cloud_arg.points.push_back(newPoint);
00606
00607 ++i;
00608 }
00609 }
00610 };
00611
00612 }
00613 }
00614
00615
00616 #endif