point_cloud_to_camera.cpp
Go to the documentation of this file.
00001 
00004 //#define USE_MT_NODE_HANDLE
00005 #include <boost/bind.hpp>
00006 #include <boost/format.hpp>
00007 #include <cv_bridge/cv_bridge.h>
00008 #include <image_transport/image_transport.h>
00009 #include <limits>
00010 #include <nodelet/nodelet.h>
00011 #include <opencv2/opencv.hpp>
00012 #include <pcl/io/io.h>
00013 #include <pluginlib/class_list_macros.h>
00014 #include <ros/ros.h>
00015 #include <sensor_msgs/CameraInfo.h>
00016 #include <sensor_msgs/image_encodings.h>
00017 #include <sensor_msgs/PointCloud2.h>
00018 #include <tf/transform_datatypes.h>
00019 #include <tf/transform_listener.h>
00020 
00021 #include <deque>          // std::deque
00022 #include <list>           // std::list
00023 
00024 #include <boost/shared_ptr.hpp>
00025 
00026 #define NO_EXTTYPE
00027 #include <stdio.h>
00028 #include "dynamic/num_array.h"
00029 
00030 #include <QtGui/QApplication>
00031 #include <QtGui/QLabel>
00032 #include <QtCore/QBasicTimer>
00033 #include <QtGui/QPainter>
00034 #include <QtGui/QDialog>
00035 #include <QtGui/QMainWindow>
00036 //#include <QtGui/QMessageBox>
00037 #include <QtGui/QKeyEvent>
00038 #include <QtGui/QMouseEvent>
00039 //
00040 //#include <GL/glut.h>
00041 
00042 //#include "GL/gl.h"
00043 #include "GL/glew.h"
00044 #include "GL/freeglut.h"
00045 #include <GL/glut.h>
00046 
00047 #include "geom/nmmatrix.h"
00048 
00049 using namespace exttype;
00050 
00051 int getFieldIndex(const sensor_msgs::PointCloud2 &cloud, const std::string fieldName) {
00052     for (size_t i = 0; i < cloud.fields.size(); i++) {
00053         if (cloud.fields[i].name == fieldName) {
00054             return i;
00055         }
00056     }
00057     return -1;
00058 }
00059 
00060 cv::Mat rotationFromTransform(const tf::Transform &t) {
00061     return (cv::Mat_<double>(3, 3) << t.getBasis()[0][0], t.getBasis()[0][1], t.getBasis()[0][2],
00062             t.getBasis()[1][0], t.getBasis()[1][1], t.getBasis()[1][2],
00063             t.getBasis()[2][0], t.getBasis()[2][1], t.getBasis()[2][2]);
00064 }
00065 
00066 cv::Mat translationFromTransform(const tf::Transform &t) {
00067     return (cv::Mat_<double>(3, 1) << t.getOrigin()[0], t.getOrigin()[1], t.getOrigin()[2]);
00068 }
00069 
00070 cv::Mat matFromCloud(sensor_msgs::PointCloud2ConstPtr cloud, const std::string fieldName, const int numElements) {
00071     const int numPoints = cloud->width * cloud->height;
00072     int fieldIndex = getFieldIndex(*cloud, fieldName);
00073     void *data = const_cast<void *>(static_cast<const void *>(&cloud->data[cloud->fields[fieldIndex].offset]));
00074     int matType;
00075     switch (cloud->fields[fieldIndex].datatype) {
00076     case sensor_msgs::PointField::FLOAT32:
00077         matType = CV_32FC1;
00078         break;
00079     case sensor_msgs::PointField::FLOAT64:
00080         matType = CV_64FC1;
00081         break;
00082     case sensor_msgs::PointField::UINT8:
00083         matType = CV_8UC1;
00084         break;
00085     default:
00086         assert (0);
00087         break;
00088     }
00089     return cv::Mat(numPoints, numElements, matType, data, cloud->point_step);
00090 };
00091 
00092 void glcheck() {
00093     GLenum errCode;
00094     const GLubyte *errString;
00095     if ((errCode = glGetError()) != GL_NO_ERROR) {
00096         errString = gluErrorString(errCode);
00097         fprintf (stderr, "OpenGL Error: %s, code %x\n", errString,errCode);
00098         fflush(stdout);
00099         exit(1);
00100     };
00101 };
00102 
00103 //_______________________________________________________________________________________
00104 
00105 class PointCloudImage : public nodelet::Nodelet {
00106 public:
00107     PointCloudImage();
00108     virtual ~PointCloudImage();
00109     void clear();
00110     void onInit();
00111 public:
00112     QLabel * label;
00113     QImage img;
00114 public:
00115     int Width;
00116     int Height;
00117     int count;
00118     ros::NodeHandle nh;
00119     ros::NodeHandle pnh;
00120     image_transport::ImageTransport * it;//(nh);
00121 private:
00122     GLuint fbo, d_render_buf;
00123     float farVal;
00124 private:
00125     tf::TransformListener transformListener;
00126     ros::Subscriber cameraSubscriber;
00127     image_transport::Publisher imagePublisher;
00128     ros::Subscriber pointCloudSub;
00129     dynamic::num_array<float,2> laser_image;
00130     std::string fixedFrame;
00131     std::string camera_topic;
00132     //
00133     std::deque<cv::Mat> w_clouds; //poit clouds mapped into fixed_frame
00134     typedef std::deque<cv::Mat>::iterator w_clouds_it;
00135     //
00136     //double maxCloudAge;
00137     int pointCloudQueueSize;
00138     double waitForTransform;
00139     void init_image(int width, int height);
00140     void pointCloudCallback(const sensor_msgs::PointCloud2ConstPtr &cloudMsg);
00141     void cameraInfoCallback(const sensor_msgs::CameraInfoConstPtr &cameraInfoMsg);
00142 };
00143 
00144 PointCloudImage::PointCloudImage() :
00145     nh(),
00146     pnh("~"),
00147     //transformListener(nh,ros::Duration(100.0),true),
00148     transformListener(ros::Duration(200.0),true),
00149     fixedFrame("/map"),
00150     //maxCloudAge(10.0),
00151     pointCloudQueueSize(500),
00152     waitForTransform(2),
00153     label(0),
00154     Width(0),Height(0),count(0),it(0) {
00155         farVal = 100;
00156 }
00157 
00158 PointCloudImage::~PointCloudImage() {
00159     clear();
00160 };
00161 
00162 void PointCloudImage::clear() {
00163     if(label) {
00164         delete label;
00165     };
00166     glDeleteFramebuffers(1,&fbo);
00167     glDeleteRenderbuffers(1,&d_render_buf);
00168 };
00169 
00170 void PointCloudImage::onInit() {
00171     NODELET_INFO("PointCloudImage::onInit: Initializing...");
00172     // Get and process parameters.
00173     pnh.param("fixed_frame", fixedFrame, fixedFrame);
00174     //NODELET_INFO("PointCloudImage::onInit: Fixed frame: %s.", fixedFrame.c_str());
00175     pnh.param("point_cloud_queue_size", pointCloudQueueSize, pointCloudQueueSize);
00176     pointCloudQueueSize = pointCloudQueueSize >= 1 ? pointCloudQueueSize : 1;
00177     //NODELET_INFO("PointCloudImage::onInit: Point cloud queue size: %i.", pointCloudQueueSize);
00178     pnh.param("wait_for_transform", waitForTransform, waitForTransform);
00179     waitForTransform = waitForTransform >= 0.0 ? waitForTransform : 0.0;
00180     //NODELET_INFO("PointCloudImage::onInit: Wait for transform timeout: %.2f s.", waitForTransform);
00181     pnh.param("camera_topic", camera_topic, std::string("openni_camera"));
00182 //    pnh.param("camera_frame", camera_frame, camera_topic);
00183 //    pnh.param("laser_frame", laser_frame, std::string("/laser"));
00184     //NODELET_INFO("PointCloudImage::onInit: camera_topic: %s.", camera_topic.c_str());
00185     std::string pclInTopic;
00186     pnh.param("scan_point_cloud", pclInTopic, std::string("scan_point_cloud"));
00187     //
00188     cameraSubscriber = nh.subscribe(camera_topic+"/camera_info", 1, &PointCloudImage::cameraInfoCallback,this);
00189     std::cout<<"Subscribed "<<camera_topic+"/camera_info"<<"\n"; fflush(stdout);
00190     pointCloudSub = nh.subscribe<sensor_msgs::PointCloud2>(pclInTopic, 10, &PointCloudImage::pointCloudCallback, this);
00191     std::cout<<"Subscribed "<<pclInTopic<<"\n"; fflush(stdout);
00192     it = new image_transport::ImageTransport(nh);
00193     imagePublisher = it->advertise(camera_topic+"/laser_image", 5);
00194     std::cout<<"Advertised "<<camera_topic+"/laser_image"<<"\n"; fflush(stdout);
00195     label = new QLabel();
00196 #ifndef DISPLAY
00197     label->setVisible(false);
00198 #else
00199     label->show();
00200 #endif
00201     label->setScaledContents(true);
00202 }
00203 
00204 void PointCloudImage::init_image(int width, int height) {
00205     Width = width;
00206     Height = height;
00207     img = QImage(Width, Height, QImage::Format_RGB32);
00208     label->resize(Width*2,Height*2);
00209     //
00210     glutInitWindowSize(Width,Height);
00211     int argc1=0;
00212     char *argv1[0];
00213     glutInit(&argc1, argv1);
00214     glutCreateWindow("GLEW window of the RIGHT size");
00215     glewExperimental=GL_TRUE;
00216     GLenum err = glewInit();
00217     if (GLEW_OK != err) {
00218         /* Problem: glewInit failed, something is seriously wrong. */
00219         fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
00220         exit(1);
00221     };
00222     printf("Vendor: %s\n", glGetString (GL_VENDOR));
00223     printf("Renderer: %s\n", glGetString (GL_RENDERER));
00224     printf("Version: %s\n", glGetString (GL_VERSION));
00225     fflush(stdout);
00226     //
00227     glGenFramebuffers(1,&fbo);
00228     glGenRenderbuffers(1,&d_render_buf);
00229     glBindFramebuffer(GL_FRAMEBUFFER,fbo);
00230     //
00231     glBindRenderbuffer(GL_RENDERBUFFER,d_render_buf);
00232     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, Width, Height);
00233     glcheck();
00234     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, d_render_buf);
00235     //
00236     GLenum e = glCheckFramebufferStatus(GL_FRAMEBUFFER);
00237     if(e!=GL_FRAMEBUFFER_COMPLETE) {
00238         //perror("Error: GL FrameBuffer, ");
00239         GLenum errCode;
00240         const GLubyte *errString;
00241 
00242         if ((errCode = glGetError()) != GL_NO_ERROR) {
00243             errString = gluErrorString(errCode);
00244             fprintf (stderr, "OpenGL Error: %s, %x, %x\n", errString,e,errCode);
00245 
00246             fflush(stdout);
00247         }
00248 //       std::cout<<gluErrorString(e)<<"\n";
00249         exit(1);
00250     };
00251 //
00252     glEnable(GL_DEPTH_TEST);
00253     glcheck();
00254     glClear(GL_DEPTH_BUFFER_BIT);
00255     glcheck();
00256     glDisable(GL_STENCIL_TEST);
00257 };
00258 
00259 void PointCloudImage::cameraInfoCallback(const sensor_msgs::CameraInfoConstPtr &cameraInfoMsg) {
00260     //
00261     bool laser_empty = false;
00262     ++count;
00263     if(Width!=cameraInfoMsg->width) {
00264         laser_image.resize(exttype::mint2(cameraInfoMsg->width,cameraInfoMsg->height));
00265         init_image(cameraInfoMsg->width,cameraInfoMsg->height);
00266     };
00267 
00268 
00269     std::string err;
00271     transformListener.waitForTransform(cameraInfoMsg->header.frame_id, cameraInfoMsg->header.stamp, // target frame and time
00272                                        fixedFrame, cameraInfoMsg->header.stamp, // source frame and time
00273                                        fixedFrame, ros::Duration(0.01)); //    this is time critical, dont wait
00274 
00275     tf::StampedTransform tf1;
00276     try {
00277         transformListener.lookupTransform(cameraInfoMsg->header.frame_id, cameraInfoMsg->header.stamp, // target frame and time
00278                                           fixedFrame, cameraInfoMsg->header.stamp, // source frame and time
00279                                           fixedFrame, tf1);
00280     } catch (tf::TransformException ex) {
00281         std::cout<<"skipping image frame -- no tf "<<fixedFrame<<"->"<<cameraInfoMsg->header.frame_id<<"\n";
00282         laser_image << farVal;
00283         return;
00284     };
00285 
00286     glBindFramebuffer(GL_FRAMEBUFFER,fbo);
00287     glClear(GL_DEPTH_BUFFER_BIT);
00288     {// set projection matrix
00289     geom::matrixn<4> m;
00290         m << 0;
00291         m(0,0) = cameraInfoMsg->K[0]/Width*2;
00292         m(0,1) = cameraInfoMsg->K[1]/Width*2;
00293         m(1,0) = cameraInfoMsg->K[3]/Height*2;
00294         m(1,1) = cameraInfoMsg->K[4]/Height*2;
00295         m(3,3) = 1;
00296         m(2,2) = 1;
00297         glMatrixMode(GL_PROJECTION);
00298         glLoadMatrixd(&m(0,0));
00299         float v = 0.05; // cut at 5 cm
00300         glFrustum(-v,v,-v,v,v,farVal);
00301     }
00302     { //set transformation matrix to current camera
00303         double m[16];
00304         tf1.getOpenGLMatrix(m);
00305         glMatrixMode(GL_MODELVIEW);
00306         for(int j=0; j<4; ++j)m[2+j*4] = -m[2+j*4]; // invert z axis
00307         glLoadMatrixd(m);
00308     }
00309 
00310          glPointSize(5.0);
00311     for(w_clouds_it pcloud=w_clouds.begin(); pcloud!=w_clouds.end(); ++pcloud) {
00312          glBegin(GL_POINTS);
00313          cv::Mat & X = *pcloud;
00314          for(int i=0;i<X.rows;++i){
00315              glVertex3fv(&X.at<float>(i,0));
00316          };
00317          glEnd();
00318          glcheck();
00319     };
00320 
00321 //
00322 //
00323 //
00324 //
00325 //    bool laser_empty = true;
00326 //    //laser_image << 0;
00327 //    //Before drawing
00328 //    glcheck();
00329 //    glBindFramebuffer(GL_FRAMEBUFFER,fbo);
00330 //    glcheck();
00331 //    //glBindRenderbuffer(GL_RENDERBUFFER,render_buf);
00332 //    //glcheck();
00333 //    //glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_buf);
00334 //    //glcheck();
00335 //    //glViewport(0, 0, Width, Height);
00336 //    //glcheck();
00337 //    glClear(GL_DEPTH_BUFFER_BIT);
00338 //    glcheck();
00373 //
00374 //    //after drawing
00375 //    //std::vector<std::uint8_t> data(width*height*4);
00376 //    //glReadBuffer(GL_COLOR_ATTACHMENT0);
00377 //    //glReadPixels(0,0,width,height,GL_BGRA,GL_UNSIGNED_BYTE,&data[0]);
00378 //
00379 //
00380 //    // Return to onscreen rendering:
00381 //    //glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
00382 //    //glcheck();
00383 //
00384 //    //
00385 //    {
00386 //        geom::matrixn<4> m;
00387 //        m << 0;
00388 //        int l = 0;
00389 //        std::cout<<"\n";
00390 //        m(0,0) = cameraInfoMsg->K[0]/Width*2;
00391 //        m(0,1) = cameraInfoMsg->K[1]/Width*2;
00392 //        m(0,3) = 0;//cameraInfoMsg->K[2];
00393 //        m(1,0) = cameraInfoMsg->K[3]/Height*2;
00394 //        m(1,1) = cameraInfoMsg->K[4]/Height*2;
00395 //        m(1,3) = 0;//cameraInfoMsg->K[5];
00396 //        m(3,0) = 0;//cameraInfoMsg->K[6]/Height;
00397 //        m(3,1) = 0;//cameraInfoMsg->K[7]/Height;
00398 //        m(3,3) = 1;//cameraInfoMsg->K[8]/Height;
00399 //        m(2,2) = 1;//1.0/Height*2;
00400 //
00410 //        //m(4,4) = 1;
00411 //
00412 //        geom::vect4 a = m*geom::vect4(0,0,100,1);
00413 //        a = a/=a[2];
00414 //        glMatrixMode(GL_PROJECTION);
00415 //        //glLoadIdentity();
00416 //        //gluPerspective(45.0f,1, 0.1f, 100.0f);
00417 //        glLoadMatrixd(&m(0,0));
00418 //        //glFrustum(0,Width,0,Height,1,10000);
00419 //        //glFrustum(-1,1,-1,1,0.01,100);
00420 //        //GLfloat aspect = (GLfloat)Width / (GLfloat)Height;
00421 //        //glMatrixMode(GL_PROJECTION);
00422 //        //glLoadIdentity(); // Reset
00423 //        //gluPerspective(60.0f, aspect, 0.1f, 100.0f);
00424 //        //glFrustum(-1.0f,1.0f,-1.0f,1.0f,1.0f,1000.0f);
00425 //        //glFrustum(-1.1f,1.1f,-1.1f,1.1f,1.0f,1000.0f);
00426 //        //glLoadIdentity();
00427 //        //glFrustum(-1.0f,1.0f,-1.0f,1.0f,1.0f,farVal);
00428 //        //glFrustum(-0.1f,0.1f,-0.1f,0.1f,0.1f,farVal);
00429 //        float v = 0.05; // cut at 5 cm
00430 //        glFrustum(-v,v,-v,v,v,farVal);
00431 //    };
00432 //    //
00433 //
00434 //    double m[16];
00435 //    //
00436 //
00437 //    for(clouds_it pcloud=clouds.begin(); pcloud!=clouds.end(); ++pcloud) {
00438 //        const sensor_msgs::PointCloud2ConstPtr cloudMsg = *pcloud;
00439 //
00440 //        const std::string cameraFrame = cameraInfoMsg->header.frame_id;
00441 //        const std::string cloudFrame = cloudMsg->header.frame_id;
00442 //
00443 //
00444 //        //! wait only for the initial tf, otherwise dont' wait
00445 //        transformListener.waitForTransform(cameraFrame, ros::Time(0), // target frame and time
00446 //                                           cloudFrame, ros::Time(0), // source frame and time
00447 //                                           fixedFrame, ros::Duration(waitForTransform));
00448 //
00449 //        /*
00450 //                if (!transformListener.waitForTransform(cameraFrame, cameraInfoMsg->header.stamp, // target frame and time
00451 //                                                        cloudFrame, cloudMsg->header.stamp, // source frame and time
00452 //                                                        fixedFrame, ros::Duration(waitForTransform))) {
00453 //                    NODELET_WARN("PointCloudImage::pointCloudCallback: Could not transform point cloud from frame %s to camera frame %s. Skipping the image...",
00454 //                                 cloudFrame.c_str(), cameraFrame.c_str());
00455 //                    continue;
00456 //                }
00457 //        */
00458 //
00459 //        tf::StampedTransform cloudToCamStamped;
00460 //
00461 //        try {
00462 //            transformListener.lookupTransform(cameraFrame, cameraInfoMsg->header.stamp, // target frame and time
00463 //                                              //cloudFrame, cloudMsg->header.stamp-ros::Duration(0.5), // source frame and time
00464 //                                              cloudFrame, cloudMsg->header.stamp, // source frame and time
00465 //                                              fixedFrame, cloudToCamStamped);
00466 //        } catch (tf::TransformException ex) {
00467 //            ROS_ERROR("%s",ex.what());
00468 //            break;//continue;
00469 //        };
00470 //
00471 //        //
00472 //
00473 //        cloudToCamStamped.getOpenGLMatrix(m);
00474 //        glMatrixMode(GL_MODELVIEW);
00475 //        for(int j=0; j<4; ++j)m[2+j*4] = -m[2+j*4]; // invert z axis
00486 //        glLoadMatrixd(m);
00487 //        //glLoadIdentity();
00488 //        //glTranslatef(0.0f, 0.0f, -10.0f);
00489 //        glcheck();
00490 //        glPointSize(3.0);
00491 //        //glBegin(GL_QUADS);
00492 //        glBegin(GL_POINTS);
00493 //        //
00494 //
00495 //        cv::Mat camRotation = rotationFromTransform(cloudToCamStamped);
00496 //        cv::Mat camTranslation = translationFromTransform(cloudToCamStamped);
00497 //        cv::Mat objectPoints;
00498 //        cv::Mat objectPoints1;
00499 //        matFromCloud(cloudMsg, "x", 3).convertTo(objectPoints1, CV_32FC1);
00500 //        matFromCloud(cloudMsg, "x", 3).convertTo(objectPoints, CV_64FC1);
00501 //
00502 //        objectPoints1 = objectPoints1.reshape(3);
00503 //
00506 //
00507 //
00508 //        // Rigid transform with points in rows: X' = X * R + t.
00509 //        objectPoints = objectPoints * camRotation.t() + cv::repeat(camTranslation.t(), objectPoints.rows, 1);
00510 //        cv::Mat cameraMatrix(3, 3, CV_64FC1, (void*)&cameraInfoMsg->K[0]);
00511 //        cv::Mat distCoeffs(1, 5, CV_64FC1, (void*)&cameraInfoMsg->D[0]);
00512 //
00513 //        cv::Mat imagePoints;
00514 //        objectPoints = objectPoints.reshape(3);
00515 //        int numPoints = objectPoints.rows;//*objectPoints.cols;
00522 //        cv::projectPoints(objectPoints, cv::Mat::zeros(3, 1, CV_64FC1), cv::Mat::zeros(3, 1, CV_64FC1), cameraMatrix, distCoeffs, imagePoints);
00531 //
00532 //        for (int iPoint = 0; iPoint < numPoints; iPoint++) {
00533 //            //std::cout<<iPoint<<"\n"; fflush(stdout);
00534 //            const double z = objectPoints.at<double>(iPoint, 2);
00535 //            // Skip points behind the camera.
00536 //            if (z <= 0.0) {
00537 //                continue;
00538 //            }
00539 //            const cv::Vec2d pt = imagePoints.at<cv::Vec2d>(iPoint, 0);
00540 //            int xi = int(pt.val[0]);
00541 //            int yi = int(pt.val[1]);
00542 //            if (xi < 0 || yi < 0 || xi >= Width || yi >= Height) {
00543 //                continue;
00544 //            }
00545 //            //laser_image(xi,yi) = z;
00546 //            //
00547 //            //const cv::Vec3d p = objectPoints1.at<cv::Vec3d>(iPoint, 0);
00548 //            //CvPoint3D32f p = objectPoints1.at<CvPoint3D32f>(iPoint, 0);
00549 //            //double * p = &objectPoints1.at<double>(iPoint, 0);
00550 //            float * p = &objectPoints1.at<float>(iPoint, 0);
00551 //            float P[3];
00552 //            P[0] = p[0];
00553 //            P[1] = p[1];
00554 //            P[2] = p[2];
00555 //            glVertex3fv(P);
00556 //            /*
00557 //            p.x+=0.1;
00558 //            glVertex3fv(p);
00559 //            p.y+=0.1;
00560 //            glVertex3fv(&p.x);
00561 //            p.x-=0.1;
00562 //            glVertex3fv(&p.x);
00563 //            */
00564 //            //
00565 //            laser_empty = false;
00566 //        };
00572 //
00573 //        //glVertex3f(0.0f,1.0f,-1.0f);
00576 //        //glVertex3f(0.0f,10.0f,-1.0f);
00577 //        //glVertex3f(0.0f,0.0f,-10.0f);
00578 //        //glVertex3f(0.0f,0.0f,-0.2f);
00579 //        //glVertex2f(0,0);
00580 //        //glVertex2f(0.5,0.5);
00581 //        //glVertex2f(1,1);
00582 //        //glVertex2f(1.2,1);
00583 //        //glVertex2f(-1.2,-1);
00584 //
00585 //        glEnd();
00586 //
00592 //        //glVertex2f(0,-1);
00593 //        //glVertex2f(0,1);
00594 //        //glVertex2f(10,10);
00595 //        //glVertex2f(100,100);
00596 //
00597 //        //break;
00598 //    };
00599 //    //glFinish();
00600     //
00601     //glcheck();
00602     //glReadBuffer(GL_COLOR_ATTACHMENT0);//GL_DEPTH_ATTACHMENT);
00603     //glcheck();
00604     glReadPixels(0,0,Width,Height,GL_DEPTH_COMPONENT,GL_FLOAT,&laser_image[0]);
00605     glcheck();
00606     //laser_image(Width-1,Height-1) = 0.01;
00607     //laser_image(Width-3,Height-3) = 0.01;
00608     laser_image*=farVal;
00609     float min_depth = std::max(float(0.01),laser_image.min().first);
00610     float max_depth = min_depth;
00611     for(int i = 0; i < (Width) *(Height); ++i) {
00612         if (laser_image[i] <farVal && max_depth < laser_image[i]) {
00613             max_depth = laser_image[i];
00614         };
00615     };
00616     max_depth = max_depth+0.1;
00617     //float max_depth = laser_image.max().first;
00618     std::cout<<"["<<min_depth<<","<<max_depth<<"]\n";
00619     // publish image here
00620     {
00621         sensor_msgs::ImagePtr msg(new sensor_msgs::Image());
00622         msg->header = cameraInfoMsg->header;
00623         msg->encoding = sensor_msgs::image_encodings::TYPE_32FC1;
00624         if(laser_empty) {
00625             msg->data.resize(0);
00626             msg->step = 0;
00627             msg->height = 0;
00628             msg->width = 0;
00629         } else {
00630             int num_bytes = laser_image.byte_size();
00631             msg->data.resize(num_bytes);
00632             memcpy(&msg->data[0],laser_image.begin(),num_bytes);
00633             msg->step = laser_image.byte_stride(0,1);
00634             msg->height = laser_image.size()[1];
00635             msg->width = laser_image.size()[0];
00636             //
00637             {
00638                 fflush(stdout);
00639                 QRgb * pimg = (QRgb*)img.bits();
00640                 for(int i = 0; i < (Width) *(Height); ++i) {
00641                     //float * pz = &laser_image[i];
00642                     //double V = 1.0;
00643                     //pimg[i] = qRgb(pixel[0],pixel[1],pixel[2]);
00644                     pimg[i] = 0;
00645                     if(laser_image[i]<farVal) {
00646                         double v = 1/(double(laser_image[i]));
00647                         double V = (v-1/max_depth)/(1/min_depth-1/max_depth);
00648                         pimg[i] = qRgb(floor((V)*255),floor((V)*255),0);
00649                     };
00650                 };
00651                 img.setPixel(Width-2,Height-2,qRgb(255,0,255));
00652                 img.setPixel(10,10,qRgb(255,0,255));
00653                 label->setPixmap(QPixmap::fromImage(img));
00654             };
00655         };
00656         //msg->header.seq = count;
00657         imagePublisher.publish(msg);
00658     }
00659 }
00660 
00661 void PointCloudImage::pointCloudCallback(const sensor_msgs::PointCloud2ConstPtr &cloudMsg) {
00662 
00663     const int numPoints = cloudMsg->width * cloudMsg->height;
00664     const std::string cloudFrame = cloudMsg->header.frame_id;
00665     if (numPoints == 0 || cloudMsg->data.size() == 0) {
00666         return;
00667     };
00668 
00670     transformListener.waitForTransform(fixedFrame, cloudMsg->header.stamp, // target frame and time
00671                                        cloudMsg->header.frame_id, cloudMsg->header.stamp, // source frame and time
00672                                        fixedFrame, ros::Duration(waitForTransform));
00673 
00674     tf::StampedTransform tf1;
00675     try {
00676         transformListener.lookupTransform(fixedFrame, cloudMsg->header.stamp, // target frame and time
00677                                           cloudMsg->header.frame_id, cloudMsg->header.stamp, // source frame and time
00678                                           fixedFrame, tf1);
00679     } catch (tf::TransformException ex) {
00680         std::cout<<"skipping scan -- no tf "<<cloudMsg->header.frame_id<<"->"<<fixedFrame<<"\n";
00681         return;
00682     };
00683 
00684     if(w_clouds.size() >=  pointCloudQueueSize) {
00685         w_clouds.pop_back();
00686     };
00687 
00688     cv::Mat camRotation;
00689     rotationFromTransform(tf1).convertTo(camRotation,CV_32FC1);
00690     cv::Mat camTranslation;
00691     translationFromTransform(tf1).convertTo(camTranslation,CV_32FC1);
00692     cv::Mat objectPoints;
00693     matFromCloud(cloudMsg, "x", 3).convertTo(objectPoints, CV_32FC1);
00694     objectPoints = objectPoints * camRotation.t() + cv::repeat(camTranslation.t(), objectPoints.rows, 1);
00695     objectPoints = objectPoints.reshape(3);
00696     w_clouds.push_front(objectPoints);
00697 }
00698 
00699 //___________________________________________________________
00700 
00701 class myApp : public QApplication {
00702 public:
00703     QLabel label;
00704     PointCloudImage node;
00705     int timer_count;
00706 public:
00707     myApp(int & argc, char ** argv):QApplication(argc,argv) {
00708         timer_count = 0;
00709         node.onInit();
00710         startTimer(1000/20);
00711     };
00712     //
00713     ~myApp() {
00714     };
00715 
00716     void timerEvent(QTimerEvent * event) {
00717         ros::spinOnce();
00718         ++timer_count;
00719         if(node.count<1) {
00720             if(timer_count % 100 ==0) {
00721                 std::cout<<"waiting for inputs\n";
00722                 std::cout.flush();
00723             };
00724         };
00725         //
00726         if(!ros::ok()) {
00727             //ros::shutdown();
00728             printf("quitting");
00729             fflush(stdout);
00730             exit(0);
00731         };
00732     };
00733     bool notify(QObject * receiver, QEvent * ev) {
00734         if(ev->type() == QEvent::MouseButtonPress) {
00735             QMouseEvent * e = static_cast<QMouseEvent *>(ev);
00736             if(e->button()==Qt::LeftButton) {
00737                 return true;
00738             };
00739         };
00740         if(ev->type() == QEvent::KeyPress) {
00741             QKeyEvent * e = static_cast<QKeyEvent *>(ev);
00742             if(e->key() == Qt::Key_Backspace) {
00743                 return true;
00744             } else if(e->key() == Qt::Key_Return) {
00745                 return true;
00746             } else if(e->key() == Qt::Key_Tab) {
00747                 return true;
00748             } else if(e->key() == Qt::Key_Escape) {
00749                 exit(0);
00750                 return true;
00751             };
00752         };
00753         return QApplication::notify(receiver,ev);
00754     };
00755 };
00756 
00757 
00758 int main(int argc, char **argv) {
00759     ros::init(argc, argv, "point_cloud_to_image");
00760     int argc1=0;
00761     char *argv1[0];
00762     myApp * a = new myApp(argc1, argv1);
00763     a->exec();
00764     delete a;
00765 }
00766 
 All Classes Namespaces Files Functions Variables Typedefs Defines


openni_cam
Author(s): Alexander Shekhovtsov
autogenerated on Sun Dec 1 2013 17:19:20