pca_test.cpp
Go to the documentation of this file.
00001 #include <ros/ros.h>
00002 // PCL
00003 #include <pcl16/point_cloud.h>
00004 #include <pcl16/point_types.h>
00005 #include <pcl16/common/pca.h>
00006 // OpenCV
00007 #include <opencv2/core/core.hpp>
00008 #include <opencv2/imgproc/imgproc.hpp>
00009 #include <opencv2/highgui/highgui.hpp>
00010 typedef pcl16::PointCloud<pcl16::PointXYZ> XYZPointCloud;
00011 
00012 cv::RotatedRect fit2DMassEllipse(XYZPointCloud& obj_cloud)
00013 {
00014   pcl16::PCA<pcl16::PointXYZ> pca;
00015   XYZPointCloud cloud_no_z;
00016   cloud_no_z.header = obj_cloud.header;
00017   cloud_no_z.width = obj_cloud.size();
00018   cloud_no_z.height = 1;
00019   cloud_no_z.is_dense = false;
00020   cloud_no_z.resize(obj_cloud.size());
00021   if (obj_cloud.size() < 3)
00022   {
00023     ROS_WARN_STREAM("Too few points to find ellipse");
00024     cv::RotatedRect obj_ellipse;
00025     obj_ellipse.center.x = 0.0;
00026     obj_ellipse.center.y = 0.0;
00027     obj_ellipse.angle = 0;
00028     obj_ellipse.size.width = 0;
00029     obj_ellipse.size.height = 0;
00030     return obj_ellipse;
00031   }
00032   for (unsigned int i = 0; i < obj_cloud.size(); ++i)
00033   {
00034     cloud_no_z[i] = obj_cloud[i];
00035     cloud_no_z[i].z = 0.0f;
00036   }
00037 
00038   pca.setInputCloud(cloud_no_z.makeShared());
00039   Eigen::Vector3f eigen_values;
00040   Eigen::Matrix3f eigen_vectors;
00041   Eigen::Vector4f centroid;
00042   try{
00043     ROS_INFO_STREAM("Getting mean");
00044     centroid = pca.getMean();
00045     ROS_INFO_STREAM("Getting eiven values");
00046     eigen_values = pca.getEigenValues();
00047     ROS_INFO_STREAM("Getting eiven vectors");
00048     eigen_vectors = pca.getEigenVectors();
00049   } catch(pcl16::InitFailedException ife)
00050   {
00051     ROS_WARN_STREAM("Failed to compute PCA");
00052     ROS_WARN_STREAM("ife: " << ife.what());
00053   }
00054 
00055   cv::RotatedRect obj_ellipse;
00056   obj_ellipse.center.x = centroid[0];
00057   obj_ellipse.center.y = centroid[1];
00058   obj_ellipse.angle = RAD2DEG(atan2(eigen_vectors(1,0), eigen_vectors(0,0))-0.5*M_PI);
00059   // NOTE: major axis is defined by height
00060   obj_ellipse.size.height = std::max(eigen_values(0)*0.1, 0.07);
00061   obj_ellipse.size.width = std::max(eigen_values(1)*0.1, 0.03);
00062   ROS_INFO_STREAM("Center: (" << obj_ellipse.center.x << ", " << obj_ellipse.center.y << ")");
00063   ROS_INFO_STREAM("angle: " << obj_ellipse.angle);
00064   ROS_INFO_STREAM("size: (" << obj_ellipse.size.height << ", " << obj_ellipse.size.width << ")");
00065   return obj_ellipse;
00066 }
00067 
00068 int main()
00069 {
00070   XYZPointCloud input_cloud;
00071   input_cloud.width = 2000;
00072   input_cloud.height = 1;
00073   input_cloud.is_dense = false;
00074   input_cloud.resize(input_cloud.width*input_cloud.height);
00075   for (int i = 0; i < input_cloud.points.size(); ++i)
00076   {
00077     input_cloud[i].x = 2.0 * rand() / (RAND_MAX) - 1.0;
00078     input_cloud[i].y = 2.0 * rand() / (RAND_MAX) - 1.0;
00079     input_cloud[i].z = 1.0 * rand() / (RAND_MAX);
00080   }
00081   // TODO: Populate input_cloud
00082   cv::RotatedRect ellipse = fit2DMassEllipse(input_cloud);
00083   return 0;
00084 }


tabletop_pushing
Author(s): Tucker Hermans
autogenerated on Wed Nov 27 2013 11:59:44