Go to the documentation of this file.00001 #include <ros/ros.h>
00002 #include <pcl17/point_types.h>
00003 #include <pcl17_ros/point_cloud.h>
00004 #include <pcl17/console/print.h>
00005 #include <pcl17/console/parse.h>
00006 #include <furniture_classification/FittedModels.h>
00007 #include <vector>
00008
00009 using namespace std;
00010
00011 class FilterNode {
00012 public:
00013 FilterNode(int n) {
00014
00015 this->n = n;
00016
00017 ros::NodeHandle nh;
00018 pub = nh.advertise<pcl17::PointCloud<pcl17::PointNormal> >(
00019 "/fitted_models", 1);
00020
00021 for (int i = 0; i < n; i++) {
00022 std::string i_str = boost::lexical_cast<std::string>(i);
00023 sub.push_back(
00024 nh.subscribe<furniture_classification::FittedModels>(
00025 "/fitted_models" + i_str, 1, &FilterNode::models_cb,
00026 this));
00027 }
00028 }
00029
00030 void models_cb(const furniture_classification::FittedModelsConstPtr & msg) {
00031 fitted.push_back(msg);
00032
00033 if (fitted.size() == n) {
00034
00035 pcl17::PointCloud<pcl17::PointNormal>::Ptr res(new pcl17::PointCloud<pcl17::PointNormal>);
00036 res->header.frame_id = msg->frame_id;
00037
00038 std::map<std::string,
00039 std::vector<pcl17::PointCloud<pcl17::PointNormal>::Ptr> > pmap;
00040 std::map<std::string, std::vector<float> > smap;
00041
00042 for (int i = 0; i < n; i++) {
00043 for (int j = 0; j < fitted[i]->classes.size(); j++) {
00044 pcl17::PointCloud<pcl17::PointNormal>::Ptr p(
00045 new pcl17::PointCloud<pcl17::PointNormal>);
00046 pcl17::fromROSMsg(fitted[i]->models[j], *p);
00047 pmap[fitted[i]->classes[j]].push_back(p);
00048 smap[fitted[i]->classes[j]].push_back(fitted[i]->scores[j]);
00049 }
00050 }
00051
00052 for (std::map<std::string,
00053 std::vector<pcl17::PointCloud<pcl17::PointNormal>::Ptr> >::iterator it =
00054 pmap.begin(); it != pmap.end(); it++) {
00055
00056 vector<pcl17::PointCloud<pcl17::PointNormal>::Ptr> result_vector;
00057
00058 result_vector = removeIntersecting(it->second, smap[it->first]);
00059
00060 for (int i = 0; i < result_vector.size(); i++) {
00061 *res += *result_vector[i];
00062 }
00063
00064 }
00065
00066 pub.publish(res);
00067 fitted.clear();
00068
00069 }
00070
00071 }
00072
00073 bool intersectXY(const pcl17::PointCloud<pcl17::PointNormal> & cloud1,
00074 const pcl17::PointCloud<pcl17::PointNormal> & cloud2) {
00075
00076 pcl17::PointNormal min1, max1, min2, max2;
00077 pcl17::getMinMax3D<pcl17::PointNormal>(cloud1, min1, max1);
00078 pcl17::getMinMax3D<pcl17::PointNormal>(cloud2, min2, max2);
00079
00080 bool intersectX, intersectY;
00081 if (min1.x < min2.x)
00082 intersectX = max1.x > min2.x;
00083 else if (min1.x > min2.x)
00084 intersectX = max2.x > min1.x;
00085 else
00086
00087 intersectX = true;
00088
00089 if (min1.y < min2.y)
00090 intersectY = max1.y > min2.y;
00091 else if (min1.y > min2.y)
00092 intersectY = max2.y > min1.y;
00093 else
00094
00095 intersectY = true;
00096
00097 return intersectX && intersectY;
00098
00099 }
00100
00101 vector<typename pcl17::PointCloud<pcl17::PointNormal>::Ptr> removeIntersecting(
00102 vector<typename pcl17::PointCloud<pcl17::PointNormal>::Ptr> & result_,
00103 vector<float> & scores_, vector<float> * selected_scores = NULL) {
00104
00105 vector<pcl17::PointCloud<pcl17::PointNormal>::Ptr> no_intersect_result;
00106
00107 if (result_.size() == 0)
00108 return no_intersect_result;
00109
00110 for (size_t i = 0; i < result_.size(); i++) {
00111 bool best = true;
00112 for (size_t j = 0; j < result_.size(); j++) {
00113 if (intersectXY(*result_[i], *result_[j])) {
00114 if (scores_[i] > scores_[j])
00115 best = false;
00116 }
00117
00118 }
00119 if (best) {
00120 if (selected_scores) {
00121 selected_scores->push_back(scores_[i]);
00122 }
00123 no_intersect_result.push_back(result_[i]);
00124 }
00125 }
00126
00127 return no_intersect_result;
00128
00129 }
00130
00131 int n;
00132 ros::Publisher pub;
00133 std::vector<ros::Subscriber> sub;
00134 std::vector<furniture_classification::FittedModelsConstPtr> fitted;
00135
00136 };
00137
00138 int main(int argc, char **argv) {
00139
00140 int n = 0;
00141
00142 pcl17::console::parse_argument(argc, argv, "-n", n);
00143
00144 ros::init(argc, argv, "filter_node");
00145 FilterNode fn(n);
00146 ros::spin();
00147
00148 return 0;
00149 }