|
Point Cloud Library (PCL)
1.4.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2010, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 * $Id: point_cloud_handlers.hpp 3771 2012-01-01 06:58:14Z rusu $ 00035 * 00036 */ 00037 00038 #include <pcl/console/time.h> 00039 #include <pcl/pcl_macros.h> 00040 00042 template <typename PointT> void 00043 pcl::visualization::PointCloudColorHandlerCustom<PointT>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const 00044 { 00045 if (!capable_) 00046 return; 00047 00048 if (!scalars) 00049 scalars = vtkSmartPointer<vtkUnsignedCharArray>::New (); 00050 scalars->SetNumberOfComponents (3); 00051 00052 vtkIdType nr_points = cloud_->points.size (); 00053 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetNumberOfTuples (nr_points); 00054 00055 // Get a random color 00056 unsigned char* colors = new unsigned char[nr_points * 3]; 00057 00058 // Color every point 00059 for (vtkIdType cp = 0; cp < nr_points; ++cp) 00060 { 00061 colors[cp * 3 + 0] = r_; 00062 colors[cp * 3 + 1] = g_; 00063 colors[cp * 3 + 2] = b_; 00064 } 00065 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetArray (colors, 3 * nr_points, 0); 00066 } 00067 00069 template <typename PointT> void 00070 pcl::visualization::PointCloudColorHandlerRandom<PointT>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const 00071 { 00072 if (!capable_) 00073 return; 00074 00075 if (!scalars) 00076 scalars = vtkSmartPointer<vtkUnsignedCharArray>::New (); 00077 scalars->SetNumberOfComponents (3); 00078 00079 vtkIdType nr_points = cloud_->points.size (); 00080 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetNumberOfTuples (nr_points); 00081 00082 // Get a random color 00083 unsigned char* colors = new unsigned char[nr_points * 3]; 00084 double r, g, b; 00085 pcl::visualization::getRandomColors (r, g, b); 00086 00087 int r_ = pcl_lrint (r * 255.0), g_ = pcl_lrint (g * 255.0), b_ = pcl_lrint (b * 255.0); 00088 00089 // Color every point 00090 for (vtkIdType cp = 0; cp < nr_points; ++cp) 00091 { 00092 colors[cp * 3 + 0] = r_; 00093 colors[cp * 3 + 1] = g_; 00094 colors[cp * 3 + 2] = b_; 00095 } 00096 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetArray (colors, 3 * nr_points, 0); 00097 } 00098 00100 template <typename PointT> 00101 pcl::visualization::PointCloudColorHandlerRGBField<PointT>::PointCloudColorHandlerRGBField (const PointCloudConstPtr &cloud) : 00102 pcl::visualization::PointCloudColorHandler<PointT>::PointCloudColorHandler (cloud) 00103 { 00104 // Handle the 24-bit packed RGB values 00105 field_idx_ = pcl::getFieldIndex (*cloud, "rgb", fields_); 00106 if (field_idx_ != -1) 00107 { 00108 capable_ = true; 00109 return; 00110 } 00111 else 00112 { 00113 field_idx_ = pcl::getFieldIndex (*cloud, "rgba", fields_); 00114 if (field_idx_ != -1) 00115 capable_ = true; 00116 else 00117 capable_ = false; 00118 } 00119 } 00120 00122 template <typename PointT> void 00123 pcl::visualization::PointCloudColorHandlerRGBField<PointT>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const 00124 { 00125 if (!capable_) 00126 return; 00127 00128 if (!scalars) 00129 scalars = vtkSmartPointer<vtkUnsignedCharArray>::New (); 00130 scalars->SetNumberOfComponents (3); 00131 00132 vtkIdType nr_points = cloud_->points.size (); 00133 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetNumberOfTuples (nr_points); 00134 unsigned char* colors = reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->GetPointer (0); 00135 00136 int j = 0; 00137 // If XYZ present, check if the points are invalid 00138 int x_idx = -1; 00139 for (size_t d = 0; d < fields_.size (); ++d) 00140 if (fields_[d].name == "x") 00141 x_idx = (int) d; 00142 00143 if (x_idx != -1) 00144 { 00145 // Color every point 00146 for (vtkIdType cp = 0; cp < nr_points; ++cp) 00147 { 00148 // Copy the value at the specified field 00149 if (!pcl_isfinite (cloud_->points[cp].x) || 00150 !pcl_isfinite (cloud_->points[cp].y) || 00151 !pcl_isfinite (cloud_->points[cp].z)) 00152 continue; 00153 00154 int idx = j * 3; 00155 colors[idx ] = cloud_->points[cp].r; 00156 colors[idx + 1] = cloud_->points[cp].g; 00157 colors[idx + 2] = cloud_->points[cp].b; 00158 j++; 00159 } 00160 } 00161 else 00162 { 00163 // Color every point 00164 for (vtkIdType cp = 0; cp < nr_points; ++cp) 00165 { 00166 int idx = cp * 3; 00167 colors[idx ] = cloud_->points[cp].r; 00168 colors[idx + 1] = cloud_->points[cp].g; 00169 colors[idx + 2] = cloud_->points[cp].b; 00170 } 00171 } 00172 } 00173 00175 template <typename PointT> 00176 pcl::visualization::PointCloudColorHandlerHSVField<PointT>::PointCloudColorHandlerHSVField (const PointCloudConstPtr &cloud) : 00177 pcl::visualization::PointCloudColorHandler<PointT>::PointCloudColorHandler (cloud) 00178 { 00179 // Check for the presence of the "H" field 00180 field_idx_ = pcl::getFieldIndex (*cloud, "h", fields_); 00181 if (field_idx_ == -1) 00182 { 00183 capable_ = false; 00184 return; 00185 } 00186 00187 // Check for the presence of the "S" field 00188 s_field_idx_ = pcl::getFieldIndex (*cloud, "s", fields_); 00189 if (s_field_idx_ == -1) 00190 { 00191 capable_ = false; 00192 return; 00193 } 00194 00195 // Check for the presence of the "V" field 00196 v_field_idx_ = pcl::getFieldIndex (*cloud, "v", fields_); 00197 if (v_field_idx_ == -1) 00198 { 00199 capable_ = false; 00200 return; 00201 } 00202 capable_ = true; 00203 } 00204 00206 template <typename PointT> void 00207 pcl::visualization::PointCloudColorHandlerHSVField<PointT>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const 00208 { 00209 if (!capable_) 00210 return; 00211 00212 if (!scalars) 00213 scalars = vtkSmartPointer<vtkUnsignedCharArray>::New (); 00214 scalars->SetNumberOfComponents (3); 00215 00216 vtkIdType nr_points = cloud_->points.size (); 00217 reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->SetNumberOfTuples (nr_points); 00218 unsigned char* colors = reinterpret_cast<vtkUnsignedCharArray*>(&(*scalars))->GetPointer (0); 00219 00220 int j = 0; 00221 // If XYZ present, check if the points are invalid 00222 int x_idx = -1; 00223 00224 for (size_t d = 0; d < fields_.size (); ++d) 00225 if (fields_[d].name == "x") 00226 x_idx = (int) d; 00227 00228 if (x_idx != -1) 00229 { 00230 // Color every point 00231 for (vtkIdType cp = 0; cp < nr_points; ++cp) 00232 { 00233 // Copy the value at the specified field 00234 if (!pcl_isfinite (cloud_->points[cp].x) || 00235 !pcl_isfinite (cloud_->points[cp].y) || 00236 !pcl_isfinite (cloud_->points[cp].z)) 00237 continue; 00238 00239 int idx = j * 3; 00240 00242 00243 // Fill color data with HSV here: 00244 if (cloud_->points[cp].s == 0) 00245 { 00246 colors[idx] = colors[idx+1] = colors[idx+2] = cloud_->points[cp].v; 00247 return; 00248 } 00249 float a = cloud_->points[cp].h / 60; 00250 int i = floor (a); 00251 float f = a - i; 00252 float p = cloud_->points[cp].v * (1 - cloud_->points[cp].s); 00253 float q = cloud_->points[cp].v * (1 - cloud_->points[cp].s * f); 00254 float t = cloud_->points[cp].v * (1 - cloud_->points[cp].s * (1 - f)); 00255 00256 switch (i) 00257 { 00258 case 0: 00259 colors[idx] = cloud_->points[cp].v; colors[idx+1] = t; colors[idx+2] = p; break; 00260 case 1: 00261 colors[idx] = q; colors[idx+1] = cloud_->points[cp].v; colors[idx+2] = p; break; 00262 case 2: 00263 colors[idx] = p; colors[idx+1] = cloud_->points[cp].v; colors[idx+2] = t; break; 00264 case 3: 00265 colors[idx] = p; colors[idx+1] = q; colors[idx+2] = cloud_->points[cp].v; break; 00266 case 4: 00267 colors[idx] = t; colors[idx+1] = p; colors[idx+2] = cloud_->points[cp].v; break; 00268 default: 00269 colors[idx] = cloud_->points[cp].v; colors[idx+1] = p; colors[idx+2] = q; break; 00270 } 00271 j++; 00272 } 00273 } 00274 else 00275 { 00276 // Color every point 00277 for (vtkIdType cp = 0; cp < nr_points; ++cp) 00278 { 00279 int idx = cp * 3; 00280 00281 // Fill color data with HSV here: 00282 if (cloud_->points[cp].s == 0) 00283 { 00284 colors[idx] = colors[idx+1] = colors[idx+2] = cloud_->points[cp].v; 00285 return; 00286 } 00287 float a = cloud_->points[cp].h / 60; 00288 int i = floor (a); 00289 float f = a - i; 00290 float p = cloud_->points[cp].v * (1 - cloud_->points[cp].s); 00291 float q = cloud_->points[cp].v * (1 - cloud_->points[cp].s * f); 00292 float t = cloud_->points[cp].v * (1 - cloud_->points[cp].s * (1 - f)); 00293 00294 switch (i) 00295 { 00296 case 0: 00297 colors[idx] = cloud_->points[cp].v; colors[idx+1] = t; colors[idx+2] = p; break; 00298 case 1: 00299 colors[idx] = q; colors[idx+1] = cloud_->points[cp].v; colors[idx+2] = p; break; 00300 case 2: 00301 colors[idx] = p; colors[idx+1] = cloud_->points[cp].v; colors[idx+2] = t; break; 00302 case 3: 00303 colors[idx] = p; colors[idx+1] = q; colors[idx+2] = cloud_->points[cp].v; break; 00304 case 4: 00305 colors[idx] = t; colors[idx+1] = p; colors[idx+2] = cloud_->points[cp].v; break; 00306 default: 00307 colors[idx] = cloud_->points[cp].v; colors[idx+1] = p; colors[idx+2] = q; break; 00308 } 00309 } 00310 } 00311 } 00312 00314 template <typename PointT> 00315 pcl::visualization::PointCloudColorHandlerGenericField<PointT>::PointCloudColorHandlerGenericField (const PointCloudConstPtr &cloud, 00316 const std::string &field_name) : pcl::visualization::PointCloudColorHandler<PointT>::PointCloudColorHandler (cloud) 00317 { 00318 field_name_ = field_name; 00319 field_idx_ = pcl::getFieldIndex (*cloud, field_name, fields_); 00320 if (field_idx_ != -1) 00321 capable_ = true; 00322 else 00323 capable_ = false; 00324 } 00325 00327 template <typename PointT> void 00328 pcl::visualization::PointCloudColorHandlerGenericField<PointT>::getColor (vtkSmartPointer<vtkDataArray> &scalars) const 00329 { 00330 if (!capable_) 00331 return; 00332 00333 if (!scalars) 00334 scalars = vtkSmartPointer<vtkFloatArray>::New (); 00335 scalars->SetNumberOfComponents (1); 00336 00337 vtkIdType nr_points = cloud_->points.size (); 00338 reinterpret_cast<vtkFloatArray*>(&(*scalars))->SetNumberOfTuples (nr_points); 00339 00340 typedef typename pcl::traits::fieldList<PointT>::type FieldList; 00341 00342 float* colors = new float[nr_points]; 00343 float field_data; 00344 00345 int j = 0; 00346 // If XYZ present, check if the points are invalid 00347 int x_idx = -1; 00348 for (size_t d = 0; d < fields_.size (); ++d) 00349 if (fields_[d].name == "x") 00350 x_idx = d; 00351 00352 if (x_idx != -1) 00353 { 00354 // Color every point 00355 for (vtkIdType cp = 0; cp < nr_points; ++cp) 00356 { 00357 // Copy the value at the specified field 00358 if (!pcl_isfinite (cloud_->points[cp].x) || !pcl_isfinite (cloud_->points[cp].y) || !pcl_isfinite (cloud_->points[cp].z)) 00359 continue; 00360 00361 uint8_t* pt_data = (uint8_t*)&cloud_->points[cp]; 00362 //memcpy (&field_data, pt_data + fields_[field_idx_].offset, sizeof (float)); 00363 memcpy (&field_data, pt_data + fields_[field_idx_].offset, pcl::getFieldSize (fields_[field_idx_].datatype)); 00364 00365 if (!pcl_isfinite (field_data)) 00366 continue; 00367 00368 colors[j] = field_data; 00369 j++; 00370 } 00371 } 00372 else 00373 { 00374 // Color every point 00375 for (vtkIdType cp = 0; cp < nr_points; ++cp) 00376 { 00377 uint8_t* pt_data = (uint8_t*)&cloud_->points[cp]; 00378 //memcpy (&field_data, pt_data + fields_[field_idx_].offset, sizeof (float)); 00379 memcpy (&field_data, pt_data + fields_[field_idx_].offset, pcl::getFieldSize (fields_[field_idx_].datatype)); 00380 00381 if (!pcl_isfinite (field_data)) 00382 continue; 00383 00384 colors[j] = field_data; 00385 j++; 00386 } 00387 } 00388 reinterpret_cast<vtkFloatArray*>(&(*scalars))->SetArray (colors, j, 0); 00389 } 00390 00392 template <typename PointT> 00393 pcl::visualization::PointCloudGeometryHandlerXYZ<PointT>::PointCloudGeometryHandlerXYZ (const PointCloudConstPtr &cloud) 00394 : pcl::visualization::PointCloudGeometryHandler<PointT>::PointCloudGeometryHandler (cloud) 00395 { 00396 field_x_idx_ = pcl::getFieldIndex (*cloud, "x", fields_); 00397 if (field_x_idx_ == -1) 00398 return; 00399 field_y_idx_ = pcl::getFieldIndex (*cloud, "y", fields_); 00400 if (field_y_idx_ == -1) 00401 return; 00402 field_z_idx_ = pcl::getFieldIndex (*cloud, "z", fields_); 00403 if (field_z_idx_ == -1) 00404 return; 00405 capable_ = true; 00406 } 00407 00409 template <typename PointT> void 00410 pcl::visualization::PointCloudGeometryHandlerXYZ<PointT>::getGeometry (vtkSmartPointer<vtkPoints> &points) const 00411 { 00412 if (!capable_) 00413 return; 00414 00415 if (!points) 00416 points = vtkSmartPointer<vtkPoints>::New (); 00417 points->SetDataTypeToFloat (); 00418 00419 vtkSmartPointer<vtkFloatArray> data = vtkSmartPointer<vtkFloatArray>::New (); 00420 data->SetNumberOfComponents (3); 00421 vtkIdType nr_points = cloud_->points.size (); 00422 00423 // Add all points 00424 vtkIdType j = 0; // true point index 00425 float* pts = new float[nr_points * 3]; 00426 00427 // If the dataset has no invalid values, just copy all of them 00428 if (cloud_->is_dense) 00429 { 00430 for (vtkIdType i = 0; i < nr_points; ++i) 00431 { 00432 pts[i * 3 + 0] = cloud_->points[i].x; 00433 pts[i * 3 + 1] = cloud_->points[i].y; 00434 pts[i * 3 + 2] = cloud_->points[i].z; 00435 } 00436 data->SetArray (&pts[0], nr_points * 3, 0); 00437 points->SetData (data); 00438 } 00439 // Need to check for NaNs, Infs, ec 00440 else 00441 { 00442 for (vtkIdType i = 0; i < nr_points; ++i) 00443 { 00444 // Check if the point is invalid 00445 if (!pcl_isfinite (cloud_->points[i].x) || !pcl_isfinite (cloud_->points[i].y) || !pcl_isfinite (cloud_->points[i].z)) 00446 continue; 00447 00448 pts[j * 3 + 0] = cloud_->points[i].x; 00449 pts[j * 3 + 1] = cloud_->points[i].y; 00450 pts[j * 3 + 2] = cloud_->points[i].z; 00451 // Set j and increment 00452 j++; 00453 } 00454 data->SetArray (&pts[0], j * 3, 0); 00455 points->SetData (data); 00456 } 00457 } 00458 00460 template <typename PointT> 00461 pcl::visualization::PointCloudGeometryHandlerSurfaceNormal<PointT>::PointCloudGeometryHandlerSurfaceNormal (const PointCloudConstPtr &cloud) 00462 : pcl::visualization::PointCloudGeometryHandler<PointT>::PointCloudGeometryHandler (cloud) 00463 { 00464 field_x_idx_ = pcl::getFieldIndex (*cloud, "normal_x", fields_); 00465 if (field_x_idx_ == -1) 00466 return; 00467 field_y_idx_ = pcl::getFieldIndex (*cloud, "normal_y", fields_); 00468 if (field_y_idx_ == -1) 00469 return; 00470 field_z_idx_ = pcl::getFieldIndex (*cloud, "normal_z", fields_); 00471 if (field_z_idx_ == -1) 00472 return; 00473 capable_ = true; 00474 } 00475 00477 template <typename PointT> void 00478 pcl::visualization::PointCloudGeometryHandlerSurfaceNormal<PointT>::getGeometry (vtkSmartPointer<vtkPoints> &points) const 00479 { 00480 if (!capable_) 00481 return; 00482 00483 if (!points) 00484 points = vtkSmartPointer<vtkPoints>::New (); 00485 points->SetDataTypeToFloat (); 00486 points->SetNumberOfPoints (cloud_->points.size ()); 00487 00488 // Add all points 00489 double p[3]; 00490 for (vtkIdType i = 0; i < (int)cloud_->points.size (); ++i) 00491 { 00492 p[0] = cloud_->points[i].normal[0]; 00493 p[1] = cloud_->points[i].normal[1]; 00494 p[2] = cloud_->points[i].normal[2]; 00495 00496 points->SetPoint (i, p); 00497 } 00498 } 00499 00501 template <typename PointT> 00502 pcl::visualization::PointCloudGeometryHandlerCustom<PointT>::PointCloudGeometryHandlerCustom (const PointCloudConstPtr &cloud, 00503 const std::string &x_field_name, const std::string &y_field_name, const std::string &z_field_name) : pcl::visualization::PointCloudGeometryHandler<PointT>::PointCloudGeometryHandler (cloud) 00504 { 00505 field_x_idx_ = pcl::getFieldIndex (*cloud, x_field_name, fields_); 00506 if (field_x_idx_ == -1) 00507 return; 00508 field_y_idx_ = pcl::getFieldIndex (*cloud, y_field_name, fields_); 00509 if (field_y_idx_ == -1) 00510 return; 00511 field_z_idx_ = pcl::getFieldIndex (*cloud, z_field_name, fields_); 00512 if (field_z_idx_ == -1) 00513 return; 00514 field_name_ = x_field_name + y_field_name + z_field_name; 00515 capable_ = true; 00516 } 00517 00519 template <typename PointT> void 00520 pcl::visualization::PointCloudGeometryHandlerCustom<PointT>::getGeometry (vtkSmartPointer<vtkPoints> &points) const 00521 { 00522 if (!capable_) 00523 return; 00524 00525 if (!points) 00526 points = vtkSmartPointer<vtkPoints>::New (); 00527 points->SetDataTypeToFloat (); 00528 points->SetNumberOfPoints (cloud_->points.size ()); 00529 00530 float data; 00531 // Add all points 00532 double p[3]; 00533 for (vtkIdType i = 0; i < (int)cloud_->points.size (); ++i) 00534 { 00535 // Copy the value at the specified field 00536 uint8_t* pt_data = (uint8_t*)&cloud_->points[i]; 00537 memcpy (&data, pt_data + fields_[field_x_idx_].offset, sizeof (float)); 00538 p[0] = data; 00539 00540 memcpy (&data, pt_data + fields_[field_y_idx_].offset, sizeof (float)); 00541 p[1] = data; 00542 00543 memcpy (&data, pt_data + fields_[field_z_idx_].offset, sizeof (float)); 00544 p[2] = data; 00545 00546 points->SetPoint (i, p); 00547 } 00548 } 00549
1.7.6.1