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 #include <pcl/pcl_config.h>
00039 #include <pcl/io/image_grabber.h>
00040 #include <pcl/point_cloud.h>
00041 #include <pcl/point_types.h>
00042 #include <pcl/io/pcd_io.h>
00043 #include <pcl/for_each_type.h>
00044 #include <pcl/io/lzf_image_io.h>
00045 #include <pcl/console/time.h>
00046
00047 #ifdef PCL_BUILT_WITH_VTK
00048 #include <vtkImageReader2.h>
00049 #include <vtkImageReader2Factory.h>
00050 #include <vtkImageData.h>
00051 #include <vtkSmartPointer.h>
00052 #include <vtkTIFFReader.h>
00053 #include <vtkPNGReader.h>
00054 #include <vtkJPEGReader.h>
00055 #include <vtkPNMReader.h>
00056 #endif
00057
00060 struct pcl::ImageGrabberBase::ImageGrabberImpl
00061 {
00063 ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
00064 const std::string& dir,
00065 float frames_per_second,
00066 bool repeat,
00067 bool pclzf_mode=false);
00069 ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
00070 const std::string& rgb_dir,
00071 const std::string& depth_dir,
00072 float frames_per_second,
00073 bool repeat);
00074 ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
00075 const std::vector<std::string>& depth_image_files,
00076 float frames_per_second,
00077 bool repeat);
00078
00079 void
00080 trigger ();
00082 void
00083 loadNextCloud ();
00084
00086 bool
00087 getCloudAt (size_t idx, pcl::PCLPointCloud2 &blob, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation,
00088 double &fx, double &fy, double &cx, double &cy) const;
00089
00091 bool
00092 getCloudVTK (size_t idx, pcl::PCLPointCloud2 &blob, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation) const;
00094 bool
00095 getCloudPCLZF (size_t idx, pcl::PCLPointCloud2 &blob, Eigen::Vector4f &origin, Eigen::Quaternionf &orientation,
00096 double &fx, double &fy, double &cx, double &cy) const;
00097
00100 void
00101 loadDepthAndRGBFiles (const std::string &dir);
00104 void
00105 loadDepthAndRGBFiles (const std::string &depth_dir, const std::string &rgb_dir);
00107
00108 void
00109 loadPCLZFFiles (const std::string &dir);
00110
00112 bool
00113 isValidExtension (const std::string &extension);
00114
00116 void
00117 rewindOnce ();
00118
00121 bool
00122 getTimestampFromFilepath (const std::string &filepath, uint64_t ×tamp) const;
00123
00124 size_t
00125 numFrames () const;
00126
00127
00128 #ifdef PCL_BUILT_WITH_VTK
00129
00130 bool
00131 getVtkImage (const std::string &filename, vtkSmartPointer<vtkImageData> &image) const;
00132 #endif//PCL_BUILT_WITH_VTK
00133
00134 pcl::ImageGrabberBase& grabber_;
00135 float frames_per_second_;
00136 bool repeat_;
00137 bool running_;
00138
00139 std::vector<std::string> depth_image_files_;
00140 std::vector<std::string> rgb_image_files_;
00141
00142 std::vector<std::string> depth_pclzf_files_;
00143 std::vector<std::string> rgb_pclzf_files_;
00144 std::vector<std::string> xml_files_;
00145
00146 size_t cur_frame_;
00147
00148 TimeTrigger time_trigger_;
00149
00150 pcl::PCLPointCloud2 next_cloud_;
00152 pcl::PointCloud<pcl::PointXYZ> next_cloud_depth_;
00153 pcl::PointCloud<pcl::PointXYZRGBA> next_cloud_color_;
00154 Eigen::Vector4f origin_;
00155 Eigen::Quaternionf orientation_;
00156 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00157 bool valid_;
00159
00160 bool pclzf_mode_;
00161
00162 float depth_image_units_;
00163
00164 bool manual_intrinsics_;
00165 double focal_length_x_;
00166 double focal_length_y_;
00167 double principal_point_x_;
00168 double principal_point_y_;
00169
00170 unsigned int num_threads_;
00171 };
00172
00174 pcl::ImageGrabberBase::ImageGrabberImpl::ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
00175 const std::string& dir,
00176 float frames_per_second,
00177 bool repeat,
00178 bool pclzf_mode)
00179 : grabber_ (grabber)
00180 , frames_per_second_ (frames_per_second)
00181 , repeat_ (repeat)
00182 , running_ (false)
00183 , depth_image_files_ ()
00184 , rgb_image_files_ ()
00185 , time_trigger_ (1.0 / static_cast<double> (std::max (frames_per_second, 0.001f)), boost::bind (&ImageGrabberImpl::trigger, this))
00186 , next_cloud_ ()
00187 , origin_ ()
00188 , orientation_ ()
00189 , valid_ (false)
00190 , pclzf_mode_(pclzf_mode)
00191 , depth_image_units_ (1E-3f)
00192 , manual_intrinsics_ (false)
00193 , focal_length_x_ (525.)
00194 , focal_length_y_ (525.)
00195 , principal_point_x_ (319.5)
00196 , principal_point_y_ (239.5)
00197 , num_threads_ (1)
00198 {
00199 if(pclzf_mode_)
00200 {
00201 loadPCLZFFiles(dir);
00202 }
00203 else
00204 {
00205 loadDepthAndRGBFiles (dir);
00206 }
00207 cur_frame_ = 0;
00208 }
00209
00211 pcl::ImageGrabberBase::ImageGrabberImpl::ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
00212 const std::string& depth_dir,
00213 const std::string& rgb_dir,
00214 float frames_per_second,
00215 bool repeat)
00216 : grabber_ (grabber)
00217 , frames_per_second_ (frames_per_second)
00218 , repeat_ (repeat)
00219 , running_ (false)
00220 , depth_image_files_ ()
00221 , rgb_image_files_ ()
00222 , time_trigger_ (1.0 / static_cast<double> (std::max (frames_per_second, 0.001f)), boost::bind (&ImageGrabberImpl::trigger, this))
00223 , next_cloud_ ()
00224 , origin_ ()
00225 , orientation_ ()
00226 , valid_ (false)
00227 , pclzf_mode_ (false)
00228 , depth_image_units_ (1E-3f)
00229 , manual_intrinsics_ (false)
00230 , focal_length_x_ (525.)
00231 , focal_length_y_ (525.)
00232 , principal_point_x_ (319.5)
00233 , principal_point_y_ (239.5)
00234 , num_threads_ (1)
00235 {
00236 loadDepthAndRGBFiles (depth_dir, rgb_dir);
00237 cur_frame_ = 0;
00238 }
00239
00241 pcl::ImageGrabberBase::ImageGrabberImpl::ImageGrabberImpl (pcl::ImageGrabberBase& grabber,
00242 const std::vector<std::string>& depth_image_files,
00243 float frames_per_second,
00244 bool repeat)
00245 : grabber_ (grabber)
00246 , frames_per_second_ (frames_per_second)
00247 , repeat_ (repeat)
00248 , running_ (false)
00249 , depth_image_files_ ()
00250 , rgb_image_files_ ()
00251 , time_trigger_ (1.0 / static_cast<double> (std::max (frames_per_second, 0.001f)), boost::bind (&ImageGrabberImpl::trigger, this))
00252 , next_cloud_ ()
00253 , origin_ ()
00254 , orientation_ ()
00255 , valid_ (false)
00256 , pclzf_mode_ (false)
00257 , depth_image_units_ (1E-3f)
00258 , manual_intrinsics_ (false)
00259 , focal_length_x_ (525.)
00260 , focal_length_y_ (525.)
00261 , principal_point_x_ (319.5)
00262 , principal_point_y_ (239.5)
00263 , num_threads_ (1)
00264 {
00265 depth_image_files_ = depth_image_files;
00266 cur_frame_ = 0;
00267 }
00268
00270 void
00271 pcl::ImageGrabberBase::ImageGrabberImpl::loadNextCloud ()
00272 {
00273 if (cur_frame_ >= numFrames ())
00274 {
00275 if (repeat_)
00276 cur_frame_ = 0;
00277 else
00278 {
00279 valid_ = false;
00280 return;
00281 }
00282 }
00283 valid_ = getCloudAt (cur_frame_, next_cloud_, origin_, orientation_,
00284 focal_length_x_, focal_length_y_, principal_point_x_, principal_point_y_);
00285 cur_frame_++;
00286 }
00287
00289 void
00290 pcl::ImageGrabberBase::ImageGrabberImpl::trigger ()
00291 {
00292 if (valid_)
00293 {
00294 grabber_.publish (next_cloud_,origin_,orientation_);
00295 }
00296
00297 loadNextCloud ();
00298 }
00299
00301 void
00302 pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles (const std::string &dir)
00303 {
00304 if (!boost::filesystem::exists (dir) || !boost::filesystem::is_directory (dir))
00305 {
00306 PCL_ERROR ("[pcl::ImageGrabber::loadDepthAndRGBFiles] Error: attempted to instantiate a pcl::ImageGrabber from a path which"
00307 " is not a directory: %s", dir.c_str ());
00308 return;
00309 }
00310 std::string pathname;
00311 std::string extension;
00312 std::string basename;
00313 boost::filesystem::directory_iterator end_itr;
00314 for (boost::filesystem::directory_iterator itr (dir); itr != end_itr; ++itr)
00315 {
00316 #if BOOST_FILESYSTEM_VERSION == 3
00317 extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->path ()));
00318 pathname = itr->path ().string ();
00319 basename = boost::filesystem::basename (itr->path ());
00320 #else
00321 extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->leaf ()));
00322 pathname = itr->path ().filename ();
00323 basename = boost::filesystem::basename (itr->leaf ());
00324 #endif
00325 if (!boost::filesystem::is_directory (itr->status ())
00326 && isValidExtension (extension))
00327 {
00328 if (basename.find ("rgb") < basename.npos)
00329 {
00330 rgb_image_files_.push_back (pathname);
00331 }
00332 else if (basename.find ("depth") < basename.npos)
00333 {
00334 depth_image_files_.push_back (pathname);
00335 }
00336 }
00337 }
00338 sort (depth_image_files_.begin (), depth_image_files_.end ());
00339 if (rgb_image_files_.size () > 0)
00340 sort (rgb_image_files_.begin (), rgb_image_files_.end ());
00341 }
00342
00343 void
00344 pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles (const std::string &depth_dir, const std::string &rgb_dir)
00345 {
00346 if (!boost::filesystem::exists (depth_dir) || !boost::filesystem::is_directory (depth_dir))
00347 {
00348 PCL_ERROR ("[pcl::ImageGrabber::loadDepthAndRGBFiles] Error: attempted to instantiate a pcl::ImageGrabber from a path which"
00349 " is not a directory: %s", depth_dir.c_str ());
00350 return;
00351 }
00352 if (!boost::filesystem::exists (rgb_dir) || !boost::filesystem::is_directory (rgb_dir))
00353 {
00354 PCL_ERROR ("[pcl::ImageGrabber::loadDepthAndRGBFiles] Error: attempted to instantiate a pcl::ImageGrabber from a path which"
00355 " is not a directory: %s", rgb_dir.c_str ());
00356 return;
00357 }
00358 std::string pathname;
00359 std::string extension;
00360 std::string basename;
00361 boost::filesystem::directory_iterator end_itr;
00362
00363 for (boost::filesystem::directory_iterator itr (depth_dir); itr != end_itr; ++itr)
00364 {
00365 #if BOOST_FILESYSTEM_VERSION == 3
00366 extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->path ()));
00367 pathname = itr->path ().string ();
00368 basename = boost::filesystem::basename (itr->path ());
00369 #else
00370 extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->leaf ()));
00371 pathname = itr->path ().filename ();
00372 basename = boost::filesystem::basename (itr->leaf ());
00373 #endif
00374 if (!boost::filesystem::is_directory (itr->status ())
00375 && isValidExtension (extension))
00376 {
00377 if (basename.find ("depth") < basename.npos)
00378 {
00379 depth_image_files_.push_back (pathname);
00380 }
00381 }
00382 }
00383
00384 for (boost::filesystem::directory_iterator itr (rgb_dir); itr != end_itr; ++itr)
00385 {
00386 #if BOOST_FILESYSTEM_VERSION == 3
00387 extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->path ()));
00388 pathname = itr->path ().string ();
00389 basename = boost::filesystem::basename (itr->path ());
00390 #else
00391 extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->leaf ()));
00392 pathname = itr->path ().filename ();
00393 basename = boost::filesystem::basename (itr->leaf ());
00394 #endif
00395 if (!boost::filesystem::is_directory (itr->status ())
00396 && isValidExtension (extension))
00397 {
00398 if (basename.find ("rgb") < basename.npos)
00399 {
00400 rgb_image_files_.push_back (pathname);
00401 }
00402 }
00403 }
00404 if (depth_image_files_.size () != rgb_image_files_.size () )
00405 PCL_WARN ("[pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles] : Watch out not same amount of depth and rgb images");
00406 if (depth_image_files_.size () > 0)
00407 sort (depth_image_files_.begin (), depth_image_files_.end ());
00408 else
00409 PCL_ERROR ("[pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles] : no depth images added");
00410 if (rgb_image_files_.size () > 0)
00411 sort (rgb_image_files_.begin (), rgb_image_files_.end ());
00412 else
00413 PCL_ERROR ("[pcl::ImageGrabberBase::ImageGrabberImpl::loadDepthAndRGBFiles] : no rgb images added");
00414 }
00415
00416
00418 void
00419 pcl::ImageGrabberBase::ImageGrabberImpl::loadPCLZFFiles (const std::string &dir)
00420 {
00421 if (!boost::filesystem::exists (dir) || !boost::filesystem::is_directory (dir))
00422 {
00423 PCL_ERROR ("[pcl::ImageGrabber::loadPCLZFFiles] Error: attempted to instantiate a pcl::ImageGrabber from a path which"
00424 " is not a directory: %s", dir.c_str ());
00425 return;
00426 }
00427 std::string pathname;
00428 std::string extension;
00429 std::string basename;
00430 boost::filesystem::directory_iterator end_itr;
00431 for (boost::filesystem::directory_iterator itr (dir); itr != end_itr; ++itr)
00432 {
00433 #if BOOST_FILESYSTEM_VERSION == 3
00434 extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->path ()));
00435 pathname = itr->path ().string ();
00436 basename = boost::filesystem::basename (itr->path ());
00437 #else
00438 extension = boost::algorithm::to_upper_copy (boost::filesystem::extension (itr->leaf ()));
00439 pathname = itr->path ().filename ();
00440 basename = boost::filesystem::basename (itr->leaf ());
00441 #endif
00442 if (!boost::filesystem::is_directory (itr->status ())
00443 && isValidExtension (extension))
00444 {
00445 if (basename.find ("rgb") < basename.npos)
00446 rgb_pclzf_files_.push_back (pathname);
00447 else if (basename.find ("depth") < basename.npos)
00448 depth_pclzf_files_.push_back (pathname);
00449 else
00450 xml_files_.push_back (pathname);
00451
00452 }
00453 }
00454 sort (depth_pclzf_files_.begin (), depth_pclzf_files_.end ());
00455 if (rgb_pclzf_files_.size () > 0)
00456 sort (rgb_pclzf_files_.begin (), rgb_pclzf_files_.end ());
00457 sort (xml_files_.begin(), xml_files_.end());
00458 if (depth_pclzf_files_.size() != xml_files_.size())
00459 {
00460 PCL_ERROR("[pcl::ImageGrabber::loadPCLZFFiles] # depth clouds != # xml files\n");
00461 return;
00462 }
00463 if (depth_pclzf_files_.size() != rgb_pclzf_files_.size() && rgb_pclzf_files_.size() > 0)
00464 {
00465 PCL_ERROR("[pcl::ImageGrabber::loadPCLZFFiles] # depth clouds != # rgb clouds\n");
00466 return;
00467 }
00468 }
00470 bool
00471 pcl::ImageGrabberBase::ImageGrabberImpl::isValidExtension (const std::string &extension)
00472 {
00473 bool valid;
00474 if(pclzf_mode_)
00475 {
00476 valid = extension == ".PCLZF" || extension == ".XML";
00477 }
00478 else
00479 {
00480 valid = extension == ".TIFF" || extension == ".PNG"
00481 || extension == ".JPG" || extension == ".JPEG"
00482 || extension == ".PPM";
00483 }
00484 return (valid);
00485 }
00486
00487 void
00488 pcl::ImageGrabberBase::ImageGrabberImpl::rewindOnce ()
00489 {
00490 if (cur_frame_ > 0)
00491 cur_frame_--;
00492 }
00493
00495 bool
00496 pcl::ImageGrabberBase::ImageGrabberImpl::getTimestampFromFilepath (
00497 const std::string &filepath,
00498 uint64_t ×tamp) const
00499 {
00500
00501 char timestamp_str[256];
00502 int result = std::sscanf (boost::filesystem::basename (filepath).c_str (),
00503 "frame_%22s_%*s",
00504 timestamp_str);
00505 if (result > 0)
00506 {
00507
00508 boost::posix_time::ptime cur_date = boost::posix_time::from_iso_string (timestamp_str);
00509 boost::posix_time::ptime zero_date (
00510 boost::gregorian::date (1970,boost::gregorian::Jan,1));
00511 timestamp = (cur_date - zero_date).total_microseconds ();
00512 return (true);
00513 }
00514 return (false);
00515 }
00516
00518 bool
00519 pcl::ImageGrabberBase::ImageGrabberImpl::getCloudAt (size_t idx,
00520 pcl::PCLPointCloud2 &blob,
00521 Eigen::Vector4f &origin,
00522 Eigen::Quaternionf &orientation,
00523 double &fx,
00524 double &fy,
00525 double &cx,
00526 double &cy) const
00527 {
00528 if (depth_image_files_.size () > 0)
00529 {
00530 fx = focal_length_x_;
00531 fy = focal_length_y_;
00532 cx = principal_point_x_;
00533 cy = principal_point_y_;
00534 return (getCloudVTK (idx, blob, origin, orientation) );
00535 }
00536 else if (depth_pclzf_files_.size () > 0)
00537 return (getCloudPCLZF (idx, blob, origin, orientation, fx, fy, cx, cy) );
00538 else
00539 {
00540 PCL_ERROR ("[pcl::ImageGrabber::getCloudAt] Could not find VTK or PCLZF files.\n");
00541 return (false);
00542 }
00543 }
00544
00545 bool
00546 pcl::ImageGrabberBase::ImageGrabberImpl::getCloudVTK (size_t idx,
00547 pcl::PCLPointCloud2 &blob,
00548 Eigen::Vector4f &origin,
00549 Eigen::Quaternionf &orientation) const
00550 {
00551 #ifdef PCL_BUILT_WITH_VTK
00552 if (idx > depth_image_files_.size ())
00553 {
00554 return (false);
00555 }
00556 unsigned short* depth_pixel;
00557 unsigned char* color_pixel;
00558 vtkSmartPointer<vtkImageData> depth_image;
00559 vtkSmartPointer<vtkImageData> rgb_image;
00560 const std::string &depth_image_file = depth_image_files_[idx];
00561
00562 if (rgb_image_files_.size () != 0)
00563 {
00564 const std::string &rgb_image_file = rgb_image_files_[idx];
00565
00566 if (!getVtkImage (rgb_image_file, rgb_image) )
00567 {
00568 return (false);
00569 }
00570 }
00571 if (!getVtkImage (depth_image_file, depth_image) )
00572 {
00573 return (false);
00574 }
00575 int* dims = depth_image->GetDimensions ();
00576
00577
00578 depth_pixel = static_cast<unsigned short*>(depth_image->GetScalarPointer ());
00579
00580
00581 float scaleFactorX, scaleFactorY;
00582 float centerX, centerY;
00583 if (manual_intrinsics_)
00584 {
00585 scaleFactorX = 1.f / static_cast<float> (focal_length_x_);
00586 scaleFactorY = 1.f / static_cast<float> (focal_length_y_);
00587 centerX = static_cast<float> (principal_point_x_);
00588 centerY = static_cast<float> (principal_point_y_);
00589 }
00590 else
00591 {
00592
00593 scaleFactorX = scaleFactorY = 1/525.f * 640.f / static_cast<float> (dims[0]);
00594 centerX = ((float)dims[0] - 1.f)/2.f;
00595 centerY = ((float)dims[1] - 1.f)/2.f;
00596 }
00597
00598 if(rgb_image_files_.size() > 0)
00599 {
00600 pcl::PointCloud<pcl::PointXYZRGBA> cloud_color;
00601 cloud_color.width = dims[0];
00602 cloud_color.height = dims[1];
00603 cloud_color.is_dense = false;
00604 cloud_color.points.resize (depth_image->GetNumberOfPoints ());
00605
00606 for (int y = 0; y < dims[1]; ++y)
00607 {
00608 for (int x = 0; x < dims[0]; ++x, ++depth_pixel)
00609 {
00610 pcl::PointXYZRGBA &pt = cloud_color.at (x,y);
00611 float depth = static_cast<float> (*depth_pixel) * depth_image_units_;
00612 if (depth == 0.0f)
00613 pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN ();
00614 else
00615 {
00616 pt.x = (static_cast<float> (x) - centerX) * scaleFactorX * depth;
00617 pt.y = (static_cast<float> (y) - centerY) * scaleFactorY * depth;
00618 pt.z = depth;
00619 }
00620
00621 color_pixel = reinterpret_cast<unsigned char*> (rgb_image->GetScalarPointer (x, y, 0));
00622 pt.r = color_pixel[0];
00623 pt.g = color_pixel[1];
00624 pt.b = color_pixel[2];
00625 }
00626 }
00627
00628 uint64_t timestamp;
00629 if (getTimestampFromFilepath (depth_image_file, timestamp))
00630 {
00631 cloud_color.header.stamp = timestamp;
00632 }
00633
00634 pcl::toPCLPointCloud2 (cloud_color, blob);
00635 }
00636 else
00637 {
00638 pcl::PointCloud<pcl::PointXYZ> cloud;
00639 cloud.width = dims[0];
00640 cloud.height = dims[1];
00641 cloud.is_dense = false;
00642 cloud.points.resize (depth_image->GetNumberOfPoints ());
00643 for (int y = 0; y < dims[1]; ++y)
00644 {
00645 for (int x = 0; x < dims[0]; ++x, ++depth_pixel)
00646 {
00647 pcl::PointXYZ &pt = cloud.at (x,y);
00648 float depth = static_cast<float> (*depth_pixel) * depth_image_units_;
00649 if (depth == 0.0f)
00650 pt.x = pt.y = pt.z = std::numeric_limits<float>::quiet_NaN ();
00651 else
00652 {
00653 pt.x = ((float)x - centerX) * scaleFactorX * depth;
00654 pt.y = ((float)y - centerY) * scaleFactorY * depth;
00655 pt.z = depth;
00656 }
00657 }
00658 }
00659
00660 uint64_t timestamp;
00661 if (getTimestampFromFilepath (depth_image_file, timestamp))
00662 {
00663 cloud.header.stamp = timestamp;
00664 }
00665
00666 pcl::toPCLPointCloud2 (cloud, blob);
00667 }
00668
00669 origin = Eigen::Vector4f::Zero ();
00670 orientation = Eigen::Quaternionf::Identity ();
00671
00672 return (true);
00673 #else
00674 PCL_ERROR ("[pcl::ImageGrabber::loadNextCloudVTK] Attempted to read image files, but PCL was not built with VTK [no -DPCL_BUILT_WITH_VTK]. \n");
00675 return (false);
00676 #endif //PCL_BUILT_WITH_VTK
00677
00678 }
00679
00680 bool
00681 pcl::ImageGrabberBase::ImageGrabberImpl::getCloudPCLZF (size_t idx,
00682 pcl::PCLPointCloud2 &blob,
00683 Eigen::Vector4f &origin,
00684 Eigen::Quaternionf &orientation,
00685 double &fx,
00686 double &fy,
00687 double &cx,
00688 double &cy) const
00689 {
00690 if (idx > depth_pclzf_files_.size ())
00691 {
00692 return (false);
00693 }
00694
00695 const std::string &depth_pclzf_file = depth_pclzf_files_[idx];
00696 const std::string &xml_file = xml_files_[idx];
00697 if (rgb_pclzf_files_.size () > 0)
00698 {
00699 pcl::PointCloud<pcl::PointXYZRGBA> cloud_color;
00700 const std::string &rgb_pclzf_file = rgb_pclzf_files_[idx];
00701 pcl::io::LZFRGB24ImageReader rgb;
00702 pcl::io::LZFBayer8ImageReader bayer;
00703 pcl::io::LZFYUV422ImageReader yuv;
00704 pcl::io::LZFDepth16ImageReader depth;
00705 if (manual_intrinsics_)
00706 {
00707 pcl::io::CameraParameters manual_params;
00708 manual_params.focal_length_x = focal_length_x_;
00709 manual_params.focal_length_y = focal_length_y_;
00710 manual_params.principal_point_x = principal_point_x_;
00711 manual_params.principal_point_y = principal_point_y_;
00712 fx = focal_length_x_;
00713 fy = focal_length_y_;
00714 cx = principal_point_x_;
00715 cy = principal_point_y_;
00716 rgb.setParameters (manual_params);
00717 yuv.setParameters (manual_params);
00718 bayer.setParameters (manual_params);
00719 depth.setParameters (manual_params);
00720 }
00721 else
00722 {
00723 rgb.readParameters (xml_file);
00724 yuv.readParameters (xml_file);
00725 bayer.readParameters (xml_file);
00726 depth.readParameters (xml_file);
00727
00728 pcl::io::CameraParameters loaded_params = depth.getParameters ();
00729
00730 fx = loaded_params.focal_length_x;
00731 fy = loaded_params.focal_length_y;
00732 cx = loaded_params.principal_point_x;
00733 cy = loaded_params.principal_point_y;
00734 }
00735 cloud_color.is_dense = false;
00736 if (num_threads_ == 1)
00737 {
00738 if (!rgb.read (rgb_pclzf_file, cloud_color))
00739 if (!yuv.read (rgb_pclzf_file, cloud_color))
00740 bayer.read (rgb_pclzf_file, cloud_color);
00741 depth.read (depth_pclzf_file, cloud_color);
00742 }
00743 else
00744 {
00745 if (!rgb.read (rgb_pclzf_file, cloud_color))
00746 if (!yuv.readOMP (rgb_pclzf_file, cloud_color, num_threads_))
00747 bayer.read (rgb_pclzf_file, cloud_color);
00748 depth.readOMP (depth_pclzf_file, cloud_color, num_threads_);
00749 }
00750
00751 uint64_t timestamp;
00752 if (getTimestampFromFilepath (depth_pclzf_file, timestamp))
00753 {
00754 cloud_color.header.stamp = timestamp;
00755 }
00756 pcl::toPCLPointCloud2 (cloud_color, blob);
00757 }
00758 else
00759 {
00760 pcl::PointCloud<pcl::PointXYZ> cloud;
00761 pcl::io::LZFDepth16ImageReader depth;
00762 if (manual_intrinsics_)
00763 {
00764 pcl::io::CameraParameters manual_params;
00765 manual_params.focal_length_x = focal_length_x_;
00766 manual_params.focal_length_y = focal_length_y_;
00767 manual_params.principal_point_x = principal_point_x_;
00768 manual_params.principal_point_y = principal_point_y_;
00769
00770 fx = focal_length_x_;
00771 fy = focal_length_y_;
00772 cx = principal_point_x_;
00773 cy = principal_point_y_;
00774 depth.setParameters (manual_params);
00775 }
00776 else
00777 {
00778 depth.readParameters (xml_file);
00779
00780 pcl::io::CameraParameters loaded_params = depth.getParameters ();
00781 fx = loaded_params.focal_length_x;
00782 fy = loaded_params.focal_length_y;
00783 cx = loaded_params.principal_point_x;
00784 cy = loaded_params.principal_point_y;
00785 }
00786 cloud.is_dense = false;
00787 if (num_threads_ == 1)
00788 depth.read (depth_pclzf_file, cloud);
00789 else
00790 depth.readOMP (depth_pclzf_file, cloud, num_threads_);
00791
00792 uint64_t timestamp;
00793 if (getTimestampFromFilepath (depth_pclzf_file, timestamp))
00794 {
00795 cloud.header.stamp = timestamp;
00796 }
00797 pcl::toPCLPointCloud2 (cloud, blob);
00798 }
00799
00800
00801 origin = Eigen::Vector4f::Zero ();
00802 orientation = Eigen::Quaternionf::Identity ();
00803 return (true);
00804 }
00805
00807
00808 #ifdef PCL_BUILT_WITH_VTK
00809 bool
00810 pcl::ImageGrabberBase::ImageGrabberImpl::getVtkImage (
00811 const std::string &filename,
00812 vtkSmartPointer<vtkImageData> &image) const
00813 {
00814
00815 vtkSmartPointer<vtkImageReader2> reader;
00816
00817 int retval;
00818 std::string upper = boost::algorithm::to_upper_copy (filename);
00819 if (upper.find (".TIFF") < upper.npos)
00820 {
00821 vtkSmartPointer<vtkTIFFReader> tiff_reader = vtkSmartPointer<vtkTIFFReader>::New ();
00822 retval = tiff_reader->CanReadFile (filename.c_str ());
00823 reader = tiff_reader;
00824 }
00825 else if (upper.find (".PNG") < upper.npos)
00826 {
00827 vtkSmartPointer<vtkPNGReader> png_reader = vtkSmartPointer<vtkPNGReader>::New ();
00828 retval = png_reader->CanReadFile (filename.c_str ());
00829 reader = png_reader;
00830 }
00831 else if (upper.find (".JPG") < upper.npos || upper.find (".JPEG") < upper.npos)
00832 {
00833 vtkSmartPointer<vtkJPEGReader> jpg_reader = vtkSmartPointer<vtkJPEGReader>::New ();
00834 retval = jpg_reader->CanReadFile (filename.c_str ());
00835 reader = jpg_reader;
00836 }
00837 else if (upper.find (".PPM") < upper.npos)
00838 {
00839 vtkSmartPointer<vtkPNMReader> ppm_reader = vtkSmartPointer<vtkPNMReader>::New ();
00840 retval = ppm_reader->CanReadFile (filename.c_str ());
00841 reader = ppm_reader;
00842 }
00843 else
00844 {
00845 PCL_ERROR ("[pcl::ImageGrabber::getVtkImage] Attempted to access an invalid filetype: %s\n", filename.c_str ());
00846 return (false);
00847 }
00848 if (retval == 0)
00849 {
00850 PCL_ERROR ("[pcl::ImageGrabber::getVtkImage] Image file can't be read: %s\n", filename.c_str ());
00851 return (false);
00852 }
00853 else if (retval == 1)
00854 {
00855 PCL_ERROR ("[pcl::ImageGrabber::getVtkImage] Can't prove that I can read: %s\n", filename.c_str ());
00856 return (false);
00857 }
00858 reader->SetFileName (filename.c_str ());
00859 reader->Update ();
00860 image = reader->GetOutput ();
00861 return (true);
00862 }
00863 #endif //PCL_BUILT_WITH_VTK
00864
00866 size_t
00867 pcl::ImageGrabberBase::ImageGrabberImpl::numFrames () const
00868 {
00869 if (pclzf_mode_)
00870 return (depth_pclzf_files_.size ());
00871 else
00872 return (depth_image_files_.size ());
00873 }
00874
00876 pcl::ImageGrabberBase::ImageGrabberBase (const std::string& directory, float frames_per_second, bool repeat, bool pclzf_mode)
00877 : impl_ (new ImageGrabberImpl (*this, directory, frames_per_second, repeat, pclzf_mode))
00878 {
00879 }
00880
00882 pcl::ImageGrabberBase::ImageGrabberBase (const std::string& rgb_dir, const std::string &depth_dir, float frames_per_second, bool repeat)
00883 : impl_ (new ImageGrabberImpl (*this, rgb_dir, depth_dir, frames_per_second, repeat))
00884 {
00885 }
00886
00888 pcl::ImageGrabberBase::ImageGrabberBase (const std::vector<std::string>& depth_image_files, float frames_per_second, bool repeat)
00889 : impl_ (new ImageGrabberImpl (*this, depth_image_files, frames_per_second, repeat))
00890 {
00891 }
00892
00894 pcl::ImageGrabberBase::~ImageGrabberBase () throw ()
00895 {
00896 stop ();
00897 delete impl_;
00898 }
00899
00901 void
00902 pcl::ImageGrabberBase::start ()
00903 {
00904 if (impl_->frames_per_second_ > 0)
00905 {
00906 impl_->running_ = true;
00907 impl_->time_trigger_.start ();
00908 }
00909 else
00910 impl_->trigger ();
00911 }
00912
00914 void
00915 pcl::ImageGrabberBase::stop ()
00916 {
00917 if (impl_->frames_per_second_ > 0)
00918 {
00919 impl_->time_trigger_.stop ();
00920 impl_->running_ = false;
00921 }
00922 }
00923
00925 void
00926 pcl::ImageGrabberBase::trigger ()
00927 {
00928 if (impl_->frames_per_second_ > 0)
00929 return;
00930 impl_->trigger ();
00931 }
00932
00934 bool
00935 pcl::ImageGrabberBase::isRunning () const
00936 {
00937 return (impl_->running_);
00938 }
00939
00941 std::string
00942 pcl::ImageGrabberBase::getName () const
00943 {
00944 return ("ImageGrabber");
00945 }
00946
00948 void
00949 pcl::ImageGrabberBase::rewind ()
00950 {
00951 impl_->cur_frame_ = 0;
00952 }
00953
00955 float
00956 pcl::ImageGrabberBase::getFramesPerSecond () const
00957 {
00958 return (impl_->frames_per_second_);
00959 }
00960
00962 bool
00963 pcl::ImageGrabberBase::isRepeatOn () const
00964 {
00965 return (impl_->repeat_);
00966 }
00967
00969 void
00970 pcl::ImageGrabberBase::setRGBImageFiles (const std::vector<std::string>& rgb_image_files)
00971 {
00972 impl_->rgb_image_files_ = rgb_image_files;
00973 impl_->cur_frame_ = 0;
00974 }
00975
00976
00978 void
00979 pcl::ImageGrabberBase::setCameraIntrinsics (const double focal_length_x,
00980 const double focal_length_y,
00981 const double principal_point_x,
00982 const double principal_point_y)
00983 {
00984 impl_->focal_length_x_ = focal_length_x;
00985 impl_->focal_length_y_ = focal_length_y;
00986 impl_->principal_point_x_ = principal_point_x;
00987 impl_->principal_point_y_ = principal_point_y;
00988 impl_->manual_intrinsics_ = true;
00989
00990 if (impl_->valid_)
00991 {
00992 impl_->rewindOnce ();
00993 impl_->loadNextCloud ();
00994 }
00995 }
00996
00997 void
00998 pcl::ImageGrabberBase::getCameraIntrinsics (double &focal_length_x,
00999 double &focal_length_y,
01000 double &principal_point_x,
01001 double &principal_point_y) const
01002 {
01003 focal_length_x = impl_->focal_length_x_;
01004 focal_length_y = impl_->focal_length_y_;
01005 principal_point_x = impl_->principal_point_x_;
01006 principal_point_y = impl_->principal_point_y_;
01007 }
01008
01009
01010
01012 void
01013 pcl::ImageGrabberBase::setDepthImageUnits (const float units)
01014 {
01015 impl_->depth_image_units_ = units;
01016 }
01018 size_t
01019 pcl::ImageGrabberBase::numFrames () const
01020 {
01021 return (impl_->numFrames ());
01022 }
01023
01025 bool
01026 pcl::ImageGrabberBase::getCloudAt (size_t idx,
01027 pcl::PCLPointCloud2 &blob,
01028 Eigen::Vector4f &origin,
01029 Eigen::Quaternionf &orientation) const
01030 {
01031 double fx, fy, cx, cy;
01032 return (impl_->getCloudAt (idx, blob, origin, orientation, fx, fy, cx, cy));
01033 }
01034
01036 bool
01037 pcl::ImageGrabberBase::atLastFrame () const
01038 {
01039 if (impl_->cur_frame_ == numFrames () - 1)
01040 return (true);
01041 else
01042 return (false);
01043 }
01044
01046 std::string
01047 pcl::ImageGrabberBase::getCurrentDepthFileName () const
01048 {
01049 std::string pathname;
01050 if (impl_->pclzf_mode_)
01051 pathname = impl_->depth_pclzf_files_[impl_->cur_frame_];
01052 else
01053 pathname = impl_->depth_image_files_[impl_->cur_frame_];
01054 std::string basename = boost::filesystem::basename (pathname);
01055 return (basename);
01056 }
01058 std::string
01059 pcl::ImageGrabberBase::getPrevDepthFileName () const
01060 {
01061 std::string pathname;
01062 if (impl_->pclzf_mode_)
01063 pathname = impl_->depth_pclzf_files_[impl_->cur_frame_-1];
01064 else
01065 pathname = impl_->depth_image_files_[impl_->cur_frame_-1];
01066 std::string basename = boost::filesystem::basename (pathname);
01067 return (basename);
01068 }
01069
01071 std::string
01072 pcl::ImageGrabberBase::getDepthFileNameAtIndex (size_t idx) const
01073 {
01074 std::string pathname;
01075 if (impl_->pclzf_mode_)
01076 pathname = impl_->depth_pclzf_files_[idx];
01077 else
01078 pathname = impl_->depth_image_files_[idx];
01079 std::string basename = boost::filesystem::basename (pathname);
01080 return (basename);
01081 }
01082
01084 bool
01085 pcl::ImageGrabberBase::getTimestampAtIndex (size_t idx, uint64_t ×tamp) const
01086 {
01087 std::string filename;
01088 if (impl_->pclzf_mode_)
01089 filename = impl_->depth_pclzf_files_[idx];
01090 else
01091 filename = impl_->depth_image_files_[idx];
01092 return (impl_->getTimestampFromFilepath (filename, timestamp));
01093 }
01094
01096 void
01097 pcl::ImageGrabberBase::setNumberOfThreads (unsigned int nr_threads)
01098 {
01099 impl_->num_threads_ = nr_threads;
01100 }