0

I would like to use PCA on the point clouds to find the lane . So the Principle Component Analysis should work fine for this problem. So Im not sure how to correctly use PCA with Point Clouds and ROS. Here is the code that I create so far

#include <iostream>
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <vector> 
#include <sensor_msgs/LaserScan.h>
#include <sensor_msgs/PointCloud2.h>
#include <sensor_msgs/PointCloud.h>
#include <laser_geometry/laser_geometry.h>
#include <tf/transform_listener.h>
#include <Eigen/Core>
#include <pcl_ros/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl_conversions/pcl_conversions.h>
#include "ros/ros.h"
#include <pcl/common/pca.h>

using namespace std;

laser_geometry::LaserProjection projector_;
tf::TransformListener listener_;

void getOrientation (const sensor_msgs::LaserScan::ConstPtr& scan)

{
    //convert laser scan into point clouds
    sensor_msgs::PointCloud cloud;
    projector_.projectLaser(*scan, cloud);

    //Construct a buffer used by the pca analysis
    pcl::PointCloud<pcl::PointXYZ> cloud_projected, cloud_reconstructed;
    pcl::PointXYZ projected, reconstructed;
    pcl::PCA<pcl::PointXYZ> pca;

    for(size_t i = 0; i < cloud.points.size(); i++)
    {
        pca.project (cloud.points.size(i), projected);
        pca.reconstruct (projected, reconstructed);
    }

}
 int main(int argc, char **argv)
 {
    
    // Initiate a new ROS node named "talker"
    ros::init(argc, argv, "lane_detection_pca_node");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe("/scan", 1000, getOrientation);
    return 0;
    ros::spin();
}

When try to build with catkin_make I got this error:

lane_detection_pca_node.cpp:37:41:error: no matching function for call to std::vector<geometry_msgs::Point32_<std::allocator<void> >, std::allocator<geometry_msgs::Point32_<std::allocator<void> > > >::size(size_t&)’
   37 |         pca.project (cloud.points.size(i), projected);

Any help to fix it? Another example of using PCA with point clouds will be

Eigen::Vector4f pcaCentroid;
pcl::compute3dCentroid(*cloud, pcaCentroid)
...

Which one would be the correct one?

Bob9710
  • 205
  • 3
  • 15
  • Std vector doesn't have the method size() with parameters. You likely want `cloud.points[i]`. – 273K Apr 20 '23 at 06:32
  • I change and now got this error: lane_detection_pca_node.cpp:38:48: error: no matching function for call to ‘pcl::PCA::project(__gnu_cxx::__alloc_traits > >, geometry_msgs::Point32_ > >::value_type&, pcl::PointXYZ&)’ 38 | pca.project (cloud.points[i], projected); – Bob9710 Apr 20 '23 at 06:48
  • You have moved forward a bit. Don't guess, read the API manual. – 273K Apr 20 '23 at 06:51
  • Which API?You mean the PCL API? – Bob9710 Apr 20 '23 at 07:07
  • so the projected cloud is a problem – Bob9710 Apr 20 '23 at 08:21
  • ok found out . The problem is that cloud is sensor_msgs::PointCloud cloud, and the projected us pcl::PointXYZ . so I need pcl::fromROSMsg(cloud, cloud_new). Right? – Bob9710 Apr 20 '23 at 09:36
  • Sorry still stuck with this. any help how to solve the projected one? – Bob9710 Apr 21 '23 at 08:09
  • ok solve it with for(size_t i = 0; i < cloud.points.size(); i++) { pcl::PointXYZ p; p.x = cloud.points[i].x; p.y = cloud.points[i].y; p.z = cloud.points[i].z; pca.project (p, (*projected)[i]); } – Bob9710 Apr 24 '23 at 03:00

0 Answers0