point_iterator_safe.cpp
Go to the documentation of this file.
00001 
00002 #include <sensor_msgs/PointCloud2.h>
00003 #include <sensor_msgs/PointField.h>
00004 #include <pcl/common/io.h>
00005 
00006 #include "point_cloud_color/point_iterator.h"
00007 
00008 namespace point_cloud_color {
00009 
00010 template <bool SAFE> PointCloud2Iterator<SAFE>::PointCloud2Iterator(sensor_msgs::PointCloud2::Ptr pcl, std::vector<std::string> fieldNames):
00011                     pcl(pcl), fieldNames(fieldNames) {
00012     fieldOffsets.resize(fieldNames.size(), 0);
00013     fieldDataTypes.resize(fieldNames.size(), 0);
00014     for (size_t i = 0; i < fieldNames.size(); i++) {
00015         int fieldIndex = pcl::getFieldIndex(*pcl, fieldNames[i]);
00016         if (fieldIndex < 0) {
00017             fieldsAvailable[i] = false;
00018             fieldOffsets[i] = 0;
00019             fieldDataTypes[i] = 0;
00020             fieldDataSizes[i] = 0;
00021         } else {
00022             fieldsAvailable[i] = true;
00023             fieldOffsets[i] = pcl->fields[fieldIndex].offset;
00024             fieldDataTypes[i] = pcl->fields[fieldIndex].datatype;
00025             switch (pcl->fields[fieldIndex].datatype) {
00026             case sensor_msgs::PointField::INT8:
00027             case sensor_msgs::PointField::UINT8:
00028                 fieldDataSizes[i] = 1;
00029                 break;
00030             case sensor_msgs::PointField::INT16:
00031             case sensor_msgs::PointField::UINT16:
00032                 fieldDataSizes[i] = 2;
00033                 break;
00034             case sensor_msgs::PointField::FLOAT32:
00035             case sensor_msgs::PointField::INT32:
00036             case sensor_msgs::PointField::UINT32:
00037                 fieldDataSizes[i] = 4;
00038                 break;
00039             case sensor_msgs::PointField::FLOAT64:
00040                 fieldDataSizes[i] = 8;
00041                 break;
00042             }
00043         }
00044     }
00045 }
00046 
00047 //bool PointCloud2Iterator::isFieldAvailable(uint32_t fieldIndex) {
00048 //    return fieldsAvailable[fieldIndex];
00049 //}
00050 //void PointCloud2Iterator::checkFieldAvailable(uint32_t fieldIndex) {
00051 //    if (!isFieldAvailable(fieldIndex)) {
00052 //        throw std::runtime_error("Field not available.");
00053 //    }
00054 //}
00055 template <bool SAFE, class T> T PointCloud2Iterator<SAFE>::getField<T>(uint32_t pointIndex, uint32_t fieldIndex) {
00056     checkFieldAvailable(fieldIndex);
00057     return *reinterpret_cast<T*>(pcl->data.data() + pointIndex * pcl->point_step + fieldOffsets[fieldIndex]);
00058 }
00059 template <bool SAFE, class T> float PointCloud2Iterator<SAFE>::getField<T>(uint32_t pointIndex, uint32_t fieldIndex) {
00060 //    checkFieldAvailable(fieldIndex);
00061     return *reinterpret_cast<float*>(pcl->data.data() + pointIndex * pcl->point_step + fieldOffsets[fieldIndex]);
00062 }
00063 template <class T> void PointCloud2Iterator<SAFE>::setField<T>(uint32_t pointIndex, uint32_t fieldIndex, T value) {
00064 //    checkFieldAvailable(fieldIndex);
00065     *reinterpret_cast<T*>(pcl->data.data() + pointIndex * pcl->point_step + fieldOffsets[fieldIndex]) = value;
00066 }
00067 template <> void PointCloud2Iterator<SAFE>::setField<T>(uint32_t pointIndex, uint32_t fieldIndex, float value) {
00068 //    checkFieldAvailable(fieldIndex);
00069     *reinterpret_cast<float*>(pcl->data.data() + pointIndex * pcl->point_step + fieldOffsets[fieldIndex]) = value;
00070 }
00071 
00072 } // namespace point_cloud_color
00073 
00074 /*
00075 void PclColor::pointCloud2Callback(const PointCloud2::ConstPtr &pclPtr) {
00076   size_t numPoints = pclPtr->width * pclPtr->height;
00077   NODELET_INFO("PclColor::pointCloud2Callback: Point cloud received (%lu points).", numPoints);
00078 
00079   // Transform the points to a fixed frame.
00080   PointCloud2::Ptr pclFixed(new PointCloud2);
00081   if (!transformListener.waitForTransform(fixedFrame, pclPtr->header.frame_id, pclPtr->header.stamp, ros::Duration(3.0))
00082       || !pcl_ros::transformPointCloud(fixedFrame, *pclPtr, *pclFixed, transformListener)) {
00083     NODELET_WARN("Cannot transform point cloud to the fixed frame %s.", fixedFrame.data());
00084     return;
00085   }
00086 
00087   // Prepare color point cloud.
00088   PointCloud2::Ptr pclColor(new PointCloud2);
00089   pclColor->header = pclPtr->header;
00090   pclColor->width = pclPtr->width;
00091   pclColor->height = pclPtr->height;
00092   pclColor->is_bigendian = pclPtr->is_bigendian;
00093   pclColor->is_dense = pclPtr->is_dense;
00094   PointField rgbaField;
00095   rgbaField.count = 1;
00096   rgbaField.datatype = PointField::UINT32;
00097   rgbaField.name = "rgba";
00098   rgbaField.offset = 0;
00099   pclColor->fields.push_back(rgbaField);
00100   pclColor->point_step = 4;
00101   pclColor->row_step = pclColor->point_step * pclColor->width;
00102   pclColor->data.resize(pclColor->row_step * pclColor->height);
00103   vector<string> pclColorFieldNames;
00104   pclColorFieldNames.push_back("rgba");
00105   PointCloud2Iterator pclColorIter(pclColor, pclColorFieldNames);
00106 
00107   // Initialize vector with projection distances from image center, used as a quality measure.
00108   vector<double> dist(numPoints, DBL_MAX);
00109   map<string, cv_bridge::CvImageConstPtr>::iterator itImages;
00110   for (itImages = images.begin(); itImages != images.end(); itImages++) {
00111     string cameraFrame = (*itImages).first;
00112     cv_bridge::CvImageConstPtr imagePtr  = images[cameraFrame];
00113     sensor_msgs::CameraInfoConstPtr cameraInfoPtr = cameraInfos[cameraFrame];
00114     NODELET_DEBUG("Map key %s, image frame %s, camera info frame %s.", cameraFrame.data(), imagePtr->header.frame_id.data(), cameraInfoPtr->header.frame_id.data());
00115 
00116     image_geometry::PinholeCameraModel cameraModel;
00117     if (!cameraModel.fromCameraInfo(cameraInfoPtr)) {
00118       NODELET_WARN("Camera model could not be constructed from camera info. Skipping the image...");
00119       continue;
00120     }
00121 
00122     // Check relative age of the point cloud and the image. Skip the image if the time span is to large.
00123     double imageAge = (pclPtr->header.stamp - imagePtr->header.stamp).toSec();
00124     if (imageAge > maxImageAge) {
00125       NODELET_WARN("Image %.1f s > %.1f s older than point cloud. Skipping the image...", imageAge, maxImageAge);
00126       continue;
00127     }
00128     NODELET_DEBUG("PclColor::pointCloud2Callback: Using camera %s, image age %.1f s.", cameraFrame.data(), imageAge);
00129 
00130     // Transform point cloud into camera frame, skip the image if the transform is not available.
00131     PointCloud2::Ptr pclCam(new PointCloud2);
00132     if (!transformListener.waitForTransform(cameraFrame, fixedFrame, imagePtr->header.stamp, ros::Duration(3.0))
00133         || !pcl_ros::transformPointCloud(cameraFrame, *pclFixed, *pclCam, transformListener)) {
00134       NODELET_WARN("Cannot transform point cloud to camera frame %s. Skipping the image...", cameraFrame.data());
00135       continue;
00136     }
00137 
00138     vector<string> pclFieldNames;
00139     pclFieldNames.push_back("x");
00140     pclFieldNames.push_back("y");
00141     pclFieldNames.push_back("z");
00142     PointCloud2Iterator pclCamIter(pclCam, pclFieldNames);
00143     pclCamIter.resetIterator(pclCam);
00144     pclColorIter.resetIterator(pclColor);
00145 
00146     int iPoint = 0;
00147     while (pclCamIter.next() && pclColorIter.next()) {
00148       // Skip points behind the camera.
00149       if (pclCamIter.getField<float>(2) < 0) {
00150         continue;
00151       }
00152       cv::Point3d p3 = cv::Point3d(pclCamIter.getField<float>(0), pclCamIter.getField<float>(1), pclCamIter.getField<float>(2));
00153       // Get rectified image coordinates.
00154       cv::Point2d p2 = cameraModel.project3dToPixel(p3);
00155       if (unrectify) {
00156         p2 = cameraModel.unrectifyPoint(p2);
00157       }
00158       double d = hypot(cameraInfoPtr->width / 2.0 - p2.x, cameraInfoPtr->height / 2.0 - p2.y);
00159       if (d >= dist[iPoint]) {
00160         // Keep color from the previous projection which we assume is better.
00161         continue;
00162       }
00163       // TODO: Linear interpolation.
00164       int x = round(p2.x);
00165       int y = round(p2.y);
00166       // Skip points outside the image.
00167       if (x < 0 || y < 0 || x >= cameraInfoPtr->width || y >= cameraInfoPtr->height) {
00168         continue;
00169       }
00170       dist[iPoint] = d;
00171       cv::Vec3b px = imagePtr->image.at<cv::Vec3b>(y, x);
00172       pclColorIter.setField<uint32_t>(0, uint32_t(px.val[2]) << 24 | uint32_t(px.val[1]) << 16 | uint32_t(px.val[0]) << 8 | 0xffu);
00173       iPoint++;
00174     }
00175   }
00176 
00177   // Prepare output point cloud.
00178   PointCloud2::Ptr pclOut(new PointCloud2);
00179   pcl::concatenateFields(*pclPtr, *pclColor, *pclOut);
00180   pointCloud2Pub.publish(pclOut);
00181 }
00182  */
 All Classes Namespaces Files Functions Variables Typedefs


point_cloud_color
Author(s): Tomas Petricek / petrito1@cmp.felk.cvut.cz
autogenerated on Tue Dec 10 2013 14:28:16