Ask Your Question

How to transform PointCloud2 with TF?

asked 2011-02-16 19:37:06 -0600

Captain gravatar image

updated 2011-02-17 06:46:10 -0600

Eric Perko gravatar image


I'm writing a small node aggregating data from a Kinect sensor (PointCloud2) taken from different angle of view. I therefore use the tf library to transform all images in the /world frame before aggregating them with the pcl lib.

After looking through tf API doc, I found the TransformListener::transformPointCloud function to tranform PointCloud messages but nothing to transform PointCloud2 messages. I am therefore using a code like this:

sensor_msgs::convertPointCloud2ToPointCloud(pc2SensorFrame,pcSensorFrame) TfListener.transformPointCloud("/world", pcSensorFrame, pcWorldFrame); sensor_msgs::convertPointCloudToPointCloud2(pcWorldFrame,pc2WorldFrame) pcl::fromROSMsg(pc2WorldFrame,pclCloud);

It seems to work but I was wondering if there was a more direct way to transform PointCloud2 with tf avoiding the conversion in PointCloud.


edit retag flag offensive close merge delete

4 Answers

Sort by » oldest newest most voted

answered 2011-02-16 20:25:09 -0600

Lorenz gravatar image

updated 2017-11-09 18:25:00 -0600

peci1 gravatar image

I guess you are looking for the pcl_ros package. It contains functions to do exactly what you want. Have a look here:

edit flag offensive delete link more


Why is the page not available now? PCL ROS has been taken out or what?

lahiruherath gravatar imagelahiruherath ( 2017-11-09 14:51:48 -0600 )edit

This is a very old link. We've moved the documentation years ago to It's now at: In the future if you're looking for docs visit the wiki page for a package eg and click on the Code API link.

tfoote gravatar imagetfoote ( 2017-11-09 15:21:10 -0600 )edit

Thanks :). Managed to get this done using tf2. Had to do some blind manipulations since i was using python

lahiruherath gravatar imagelahiruherath ( 2017-11-09 18:05:19 -0600 )edit

answered 2017-07-13 13:18:28 -0600

Gayan Brahmanage gravatar image

updated 2017-12-06 13:45:09 -0600

This is a simple code to transform scan point cloud to base link. Use a separate script for class laser_to_points2d: for ease of use.

from math import sin, cos
import tf
import numpy as np
from sensor_msgs.msg import PointCloud
from geometry_msgs.msg import Point32

 class laser_to_points2d:
    def __init__(self,):
        self.base_link_point2d.header.frame_id = "base_link" 

    def update(self,scandata,angle_min,angle_max,angle_increment):

        for i in xrange(len(scandata)):     
            if not math.isnan(scandata[i]):

            self.base_link_point2d.points.append(Point32(px,py, 0.0))
            self.base_link_point2d.channels.append(0)# add some information if needed

You need to listen to the transformation for Odom to base_link and subscribe the scan topic

import rospy
import roslib
from sensor_msgs.msg import LaserScan
import tf
from file_name_your_ class _laser_to_points2d import laser_to_points2d

def scanCb(msg):

if __name__ == "__main__":

    rospy.init_node('main', anonymous=True) #make node  
    rospy.Subscriber("/scan", LaserScan, scanCb,queue_size = 1) 
    rate = rospy.Rate(5) # 5hz         
    listener = tf.TransformListener()           
    while not rospy.is_shutdown():

        listener.waitForTransform("/base_link", "/odom", rospy.Time(0),rospy.Duration(1.0))     
edit flag offensive delete link more


As is, this won't run. You'll need to indent everything after the if __name__ == "__main__":

jayess gravatar imagejayess ( 2017-07-13 16:38:52 -0600 )edit

Hi Gayan, I first created named laserTF package. After that I created two python files named and in the packaged src file I created. I pasted the code above into the lasertf file and the code below into the laserTransform file.

Mekateng gravatar imageMekateng ( 2017-08-11 07:01:50 -0600 )edit

And file name your class at the time I wrote lasertf. But ı got an error like below Traceback (most recent call last): File "/home/ahmet/catkin_ws/src/laserTF/src/", line 2, in <module> import rospy .... Can I learn the reason for this ?

Mekateng gravatar imageMekateng ( 2017-08-11 07:04:35 -0600 )edit

@Mekateng, you should create a new question and reference this question.

jayess gravatar imagejayess ( 2017-08-11 10:06:53 -0600 )edit

I couldn't create new question . Mr foote is closing my questions.

Mekateng gravatar imageMekateng ( 2017-08-11 11:17:06 -0600 )edit

Just follow the guidelines as @tfoote said and they won't get closed.

jayess gravatar imagejayess ( 2017-08-11 11:53:26 -0600 )edit

ı had asked my question to Gayan. but if you want to reply my question ,ı am looking forward to wait your answer bro

Mekateng gravatar imageMekateng ( 2017-08-11 16:26:35 -0600 )edit

I will, just ask a new question. Comments aren't the place for asking and answering new questions.

jayess gravatar imagejayess ( 2017-08-11 16:28:47 -0600 )edit

answered 2017-11-09 18:34:09 -0600

lahiruherath gravatar image

You can use do_transform_cloud from tf2 to get this done just have to feed in the incoming cloud with the transform. This is using Python. And you'll have to convert the tuple from lookupTransform to a TransformStamped to be fed into the function. Follow this other thread for execution

link text


edit flag offensive delete link more


I tried using this method (in python) but it somehow doesn't work as expected. That's why I used a transformation with 0 translation and 0 rotation to test, but it nevertheless changes my pointcloud. Anyone expericened something like this?

rosNewbie gravatar imagerosNewbie ( 2020-01-02 16:29:42 -0600 )edit

answered 2015-08-13 18:19:59 -0600

peci1 gravatar image

You can transform using the tf2_sensor_msgs (both C++ and Python interface, since at least Indigo):

#include <tf2_sensor_msgs.h>
#include <sensor_msgs/PointCloud2.h>
#include <geometry_msgs/TransformStamped.h>

const sensor_msgs::PointCloud2 cloud_in, cloud_out;
const geometry_msgs::TransformStamped transform;
// TODO load everything
tf2::doTransform (cloud_in, cloud_out, transform);

Or in Python:

from tf2_sensor_msgs.tf2_sensor_msgs import do_transform_cloud
cloud_out = do_transform_cloud(cloud_in, transform)

None of the codes was really tested, though I intend to use them tomorrow. If you test them and find a bug, please edit my answer. I really wonder why there aren't more tutorials for this kind of essential conversions.

edit flag offensive delete link more


I get a tf2_sensor_msgs.pycannot import name read_cloud error in Indigo. Is the transform the return value of a lookupTransform?

lucasw gravatar imagelucasw ( 2015-08-14 17:16:14 -0600 )edit

You're right, @lucasw, there seems to be a bug in do_transform_cloud . I've reported it here: .

peci1 gravatar imagepeci1 ( 2015-08-17 04:17:59 -0600 )edit

Until the bug gets fixed, you can manually copy&paste the code of the method's body and change read_cloud to read_points . The method body is here:

peci1 gravatar imagepeci1 ( 2015-08-17 04:18:47 -0600 )edit

Have anyone got this to work? Seems to be deprecated.

Azergoo gravatar imageAzergoo ( 2018-07-10 11:48:07 -0600 )edit

I tried using this method (in python) but it somehow doesn't work as expected. That's why I used a transformation with 0 translation and 0 rotation to test, but it nevertheless changes my pointcloud. Anyone expericened something like this?

rosNewbie gravatar imagerosNewbie ( 2020-01-02 16:29:21 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2011-02-16 19:37:06 -0600

Seen: 17,387 times

Last updated: Dec 06 '17