20 #include <pcl/common/transforms.h> 21 #include <pcl/features/normal_3d.h> 22 #include <pcl/filters/extract_indices.h> 27 bool Utils::getNormals(PointCloudRGB::Ptr& cloud,
double normal_radius, PointCloudNormal::Ptr& normals)
29 ROS_INFO(
"Computing normals with radius: %f", normal_radius);
30 pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> ne;
31 ne.setInputCloud(cloud);
33 pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(
new pcl::search::KdTree<pcl::PointXYZRGB>());
34 ne.setSearchMethod(tree);
37 ne.setRadiusSearch(normal_radius);
41 bool success = normals->points.size() == cloud->points.size() ?
true :
false;
48 return (cloud->size() > 1);
53 return (cloud->size() > 1);
58 return (normals->size() > 1);
63 return ((mesh->cloud.row_step*mesh->cloud.height) != 0);
68 return ((cloud_msg.row_step*cloud_msg.height) != 0);
73 for (
int i=0; i<transform.rows(); i++)
75 for (
int j=0; j<transform.cols(); j++)
77 if (std::isnan(transform(i,j)))
86 for (
size_t i = 0; i < cloud_rgb->points.size(); i++)
88 cloud_rgb->points[i].r = R;
89 cloud_rgb->points[i].g = G;
90 cloud_rgb->points[i].b = B;
96 pcl::copyPointCloud(*cloud, *cloud_rgb);
100 void Utils::cloudToROSMsg(PointCloudRGB::Ptr cloud, sensor_msgs::PointCloud2& cloud_msg,
const std::string& frameid)
102 pcl::toROSMsg(*cloud, cloud_msg);
103 cloud_msg.header.frame_id = frameid;
107 void Utils::cloudToROSMsg(
const pcl::PCLPointCloud2& cloud, sensor_msgs::PointCloud2& cloud_msg,
const std::string& frameid)
109 pcl_conversions::fromPCL(cloud, cloud_msg);
110 cloud_msg.header.frame_id = frameid;
119 std::vector<int> indices(2);
120 std::vector<float> sqr_distances(2);
121 pcl::search::KdTree<pcl::PointXYZ> tree;
122 tree.setInputCloud(cloud);
124 for (std::size_t i = 0; i < cloud->size(); ++i)
126 if (!std::isfinite((*cloud)[i].
x))
131 nres = tree.nearestKSearch(i, 2, indices, sqr_distances);
134 res += sqrt(sqr_distances[1]);
150 std::vector<int> indices(2);
151 std::vector<float> sqr_distances(2);
152 pcl::search::KdTree<pcl::PointXYZRGB> tree;
153 tree.setInputCloud(cloud);
155 for (std::size_t i = 0; i < cloud->size(); ++i)
157 if (!std::isfinite((*cloud)[i].
x))
162 nres = tree.nearestKSearch(i, 2, indices, sqr_distances);
165 res += sqrt(sqr_distances[1]);
178 Eigen::IOFormat CleanFmt(4, 0,
", ",
"\n",
"\t\t\t\t[",
"]");
179 std::cout << transform.format(CleanFmt) << std::endl;
184 Eigen::IOFormat CleanFmt(size, 0,
", ",
"\n",
"\t\t\t\t[",
"]");
185 std::cout << matrix.format(CleanFmt) << std::endl;
189 PointCloudRGB::Ptr one_point_cloud)
192 Eigen::Vector4f centroid;
193 pcl::compute3DCentroid(*cloud, centroid);
199 for(
int i=0; i<size; i++)
200 one_point_cloud->points.push_back(p);
204 double x_offset,
double y_offset,
double z_offset)
206 pcl::copyPointCloud(*cloud_in, *cloud_out);
207 for (
size_t i = 0; i < cloud_out->points.size(); i++)
209 cloud_out->points[i].x += x_offset;
210 cloud_out->points[i].y += y_offset;
211 cloud_out->points[i].z += z_offset;
216 double roll,
double pitch,
double yaw)
218 Eigen::AngleAxisf rollAngle(roll, Eigen::Vector3f::UnitX());
219 Eigen::AngleAxisf pitchAngle(pitch, Eigen::Vector3f::UnitY());
220 Eigen::AngleAxisf yawAngle(yaw, Eigen::Vector3f::UnitZ());
222 Eigen::Quaternion<float> q = rollAngle * pitchAngle * yawAngle;
224 Eigen::Matrix3f rotation = q.matrix();
228 T.block<3,3>(0,0) = rotation;
229 pcl::transformPointCloud(*cloud_in, *cloud_out, T);
235 Eigen::Vector3f& vector)
237 double x = normal->points[idx].normal_x;
238 double y = normal->points[idx].normal_y;
239 double z = normal->points[idx].normal_z;
246 std::vector<int>& source_indx, std::vector<int>& target_indx)
249 int s_row_size = source_m.row(0).size();
250 int t_row_size = target_m.row(0).size();
251 int size = s_row_size < t_row_size ? s_row_size : t_row_size;
255 for(
int i=0; i<size && count<2; i++)
258 t_row =
findOnMatrix(source_m.row(s_row), target_m, th);
262 source_indx.push_back(s_row);
263 target_indx.push_back(t_row);
268 if(count<2)
return false;
275 if(v1.size() != v2.size())
278 if (v1.isApprox(v2, threshold))
288 if (v.size()!=0 && (v.array() - value).abs().minCoeff(&index) <= threshold)
298 for(
int i=0; i<v.size() && index==-1; i++)
306 int nrows = matrix.rows();
307 int ncols = matrix.cols()-1;
310 matrix.block(0,col,nrows,ncols-col) = matrix.rightCols(ncols-col);
312 matrix.conservativeResize(nrows,ncols);
317 int nrows = matrix.rows()-1;
318 int ncols = matrix.cols();
321 matrix.block(row,0,nrows-row,ncols) = matrix.bottomRows(nrows-row);
323 matrix.conservativeResize(nrows,ncols);
static void printTransform(const Eigen::Matrix4f &transform)
Print on console transform values with matrix format.
static bool getNormals(PointCloudRGB::Ptr &cloud, double normal_radius, PointCloudNormal::Ptr &normals)
Get the normals for input cloud with specified normal's radius.
const std::string SOURCE_CLOUD_TOPIC
static bool isValidTransform(Eigen::Matrix4f transform)
Check whether transform contains valid data and is not NaN.
static void extractColFromMatrix(Eigen::MatrixXd &matrix, int col)
Supress col from matrix.
static bool searchForSameRows(Eigen::MatrixXd source_m, Eigen::MatrixXd target_m, std::vector< int > &source_indx, std::vector< int > &target_indx)
Check if both matrix have a coinciden row.
static void printMatrix(const Eigen::Ref< const Eigen::MatrixXf > &matrix, const int size)
Print on console matrix values with matrix format.
static int findOnVector(double value, const Eigen::VectorXd v, double threshold)
Find value on vector with given threshold. Returns index vector of value found. If not found returns ...
const std::string TARGET_CLOUD_TOPIC
static void cloudToXYZRGB(PointCloudXYZ::Ptr cloud, PointCloudRGB::Ptr cloud_rgb, int R, int G, int B)
Convert XYZ cloud to XYZRGB cloud with specified RGB values.
static void getVectorFromNormal(PointCloudNormal::Ptr normal, double idx, Eigen::Vector3f &vector)
Obtain normal values as a vector.
static void colorizeCloud(PointCloudRGB::Ptr cloud_rgb, int R, int G, int B)
Apply RGB values to cloud.
static bool isValidCloud(PointCloudXYZ::Ptr cloud)
Check whether cloud contains data and is not empty.
TFSIMD_FORCE_INLINE const tfScalar & y() const
static void onePointCloud(PointCloudRGB::Ptr cloud, int size, PointCloudRGB::Ptr one_point_cloud)
Apply extract indices filter to input cloud with given indices.
static bool areSameVectors(const Eigen::VectorXd v1, const Eigen::VectorXd v2, double threshold)
Check if given vectors are equal with a given tolerance (threshold).
pcl::PointCloud< pcl::Normal > PointCloudNormal
static void cloudToROSMsg(PointCloudRGB::Ptr cloud, sensor_msgs::PointCloud2 &cloud_msg, const std::string &frameid="world")
Convert XYZRGB cloud to PointCloud2.
static int findOnMatrix(const Eigen::VectorXd v, const Eigen::MatrixXd m, double threshold)
Find vector as row on matrix with given threshold. Returns index of matrix row. If not found returns ...
TFSIMD_FORCE_INLINE const tfScalar & x() const
static void extractRowFromMatrix(Eigen::MatrixXd &matrix, int row)
Supress row from matrix.
TFSIMD_FORCE_INLINE const tfScalar & z() const
static void translateCloud(PointCloudRGB::Ptr cloud_in, PointCloudRGB::Ptr cloud_out, double x_offset=0, double y_offset=0, double z_offset=0)
Apply translation to Cloud. Values given in [m].
static double computeCloudResolution(PointCloudXYZ::Ptr cloud)
Obtain the resolution of the cloud.
static void rotateCloud(PointCloudRGB::Ptr cloud_in, PointCloudRGB::Ptr cloud_out, double roll, double pitch, double yaw)
Apply rotation to cloud. Values given in [rad].
static bool isValidMesh(pcl::PolygonMesh::Ptr mesh)
Check whether mesh contains data and is not empty.
static bool isValidCloudMsg(const sensor_msgs::PointCloud2 &cloud_msg)
Check whether PointCloud2 contains data and is not empty.