polygon_filter.cpp
Go to the documentation of this file.
00001 #include <algorithm> //min, max
00002 #include <cstdlib> //rand
00003 #include "polygon_filter.h"
00007 template <class point_type1>
00008 bool point_inside_polygon(const pcl::PointCloud<point_type1>& cropping_polygon, const point_type1& query_point, int x, int y)
00009 {
00010   //For the following commenst, x is assumed horizontally and y vertically
00011   int num_intersections = 0;
00012   //Polygon Line Segment Start and End
00013   point_type1 p1,p2;
00014 
00015   for(unsigned int i = 0; i< cropping_polygon.size(); i++)
00016   {
00017     p1 = cropping_polygon[i];
00018     int next_vertex_idx = (i+1) % cropping_polygon.size();//Wrap around
00019     p2 = cropping_polygon[next_vertex_idx];
00020     //std::cout << "P1: "<< p1.x << ", " <<p1.y << "\n";
00021     //std::cout << "P2: "<< p2.x << ", " <<p2.y << "\n";
00022     //if query point is between lower ...
00023     if (query_point.data[y] > std::min(p1.data[y],p2.data[y])) {
00024       //...and upper segment end... 
00025       if (query_point.data[y] <= std::max(p1.data[y],p2.data[y])) {
00026         //Check in which half plane it is using the dot product of the segment's normal
00027         point_type1 segment_direction, normal;
00028         segment_direction.data[x] = p2.data[x]-p1.data[x];
00029         segment_direction.data[y] = p2.data[y]-p1.data[y];
00030         normal.data[x] = segment_direction.data[y];
00031         normal.data[y] = -segment_direction.data[x];
00032         //if normal points to the right, flip it to the left
00033         if(normal.data[x] > 0){
00034           normal.data[x] *= -1.0;
00035           normal.data[y] *= -1.0;
00036         }
00037         //std::cout << "N:  "<< normal.x << ", " <<normal.y << "\n";
00038         //Dot Product
00039         point_type1 query_point_rel;
00040         query_point_rel.data[x] = query_point.data[x] - p1.data[x];
00041         query_point_rel.data[y] = query_point.data[y] - p1.data[y];
00042         //std::cout << "QR: "<< query_point_rel.x << ", " <<query_point_rel.y << "\n";
00043         double dot = normal.data[x] * query_point_rel.data[x] + normal.data[y] * query_point_rel.data[y];
00044         if(dot > 0) //it's to the left, i.e. the ray 
00045           num_intersections++;
00046       }      
00047     }
00048   }
00049 
00050   if (num_intersections% 2 == 0)
00051     return false;
00052   else
00053     return true;
00054 }
00055 
00057 template <class point_type1>
00058 pcl::PointCloud<point_type1> crop_by_polygon(const pcl::PointCloud<point_type1>& cropping_polygon, const pcl::PointCloud<point_type1>& cloud_to_crop, int x, int y, bool invert)
00059 {
00060   pcl::PointCloud<point_type1> cloud_inside;
00061   cloud_inside.header =  cloud_to_crop.header;
00062 
00063   for(unsigned int i = 0; i < cloud_to_crop.size(); i++)
00064   {
00065     if(point_inside_polygon(cropping_polygon, cloud_to_crop[i], x, y) xor invert)
00066     {
00067       cloud_inside.push_back(cloud_to_crop[i]);
00068     }
00069   }
00070   return cloud_inside;
00071 }
00072 
00073 void cropping_test(){
00074 
00075       pcl::PointCloud<pcl::PointXYZ> test_cloud;
00076       pcl::PointXYZ vertex;
00077       srand(time(NULL));
00078       for(int i = 0; i < 200; i++){
00079         vertex.x = rand()/(RAND_MAX/2.0); 
00080         vertex.y = rand()/(RAND_MAX/2.0); 
00081         test_cloud.points.push_back(vertex);
00082       }
00083 
00084       pcl::PointCloud<pcl::PointXYZ> cropping_polygon;
00085       vertex.x =  0.0; vertex.y =  0.0; cropping_polygon.points.push_back(vertex);//  +------+
00086       vertex.x =  1.0; vertex.y =  0.0; cropping_polygon.points.push_back(vertex);//  |      |
00087       vertex.x =  1.0; vertex.y =  1.0; cropping_polygon.points.push_back(vertex);//  |      |
00088       vertex.x =  0.0; vertex.y =  1.0; cropping_polygon.points.push_back(vertex);//  +------+
00089       
00090       pcl::PointCloud<pcl::PointXYZ> inside_cloud = crop_by_polygon(cropping_polygon, test_cloud, 0, 1);
00091       pcl::PointCloud<pcl::PointXYZ> outside_cloud = crop_by_polygon(cropping_polygon, test_cloud, 0, 1, true);
00092       for(unsigned int i = 0; i < inside_cloud.size(); i++){
00093         std::cout << "Point Inside (" << i << "/" << inside_cloud.size() << "): "<< inside_cloud.points[i].x << ", " <<inside_cloud.points[i].y << ", " <<inside_cloud.points[i].z << "\n";
00094       }
00095       std::cout << std::endl;
00096       for(unsigned int i = 0; i < outside_cloud.size(); i++){
00097         std::cout << "Point Outside (" << i << "/" << outside_cloud.size() << "): "<< outside_cloud.points[i].x << ", " <<outside_cloud.points[i].y << ", " <<outside_cloud.points[i].z << "\n";
00098       }
00099 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


door_perception
Author(s): Felix Endres
autogenerated on Wed Dec 26 2012 16:03:53