Dear all,
given a convex hull of a plane (by using the nice pcl::ConvexHull2D ;) I want to calculate the minimum bounding 2D rectangle for the 3D points This could be done e.g. using the rotating calipers method. Isn't there something already available in the PCL for the lazy people ;) Cheers and Happy Holidays Markus  Dipl. Inf. Markus Eich Researcher DFKI Bremen Robotics Innovation Center MarySomervilleStr. 9 28359 Bremen, Germany Phone: +49 (0)421 178454105 Fax: +49 (0)421 178454150 EMail: [hidden email] Weitere Informationen: http://www.dfki.de/robotik  Deutsches Forschungszentrum fuer Kuenstliche Intelligenz GmbH Firmensitz: Trippstadter Straße 122, D67663 Kaiserslautern Geschaeftsfuehrung: Prof. Dr. Dr. h.c. mult. Wolfgang Wahlster (Vorsitzender) Dr. Walter Olthoff Vorsitzender des Aufsichtsrats: Prof. Dr. h.c. Hans A. Aukes Amtsgericht Kaiserslautern, HRB 2313 Sitz der Gesellschaft: Kaiserslautern (HRB 2313) UStId.Nr.: DE 148646973 Steuernummer: 19/673/0060/3  _______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
Hi Markus,
I have an implementation of this, but unfortunately with the many changes in PCL lately it might not work.. But let us try to make it happen :) It is a SaC approach, and the most important part was ported to PCL by Hozefa (thanks again :P) into our mapping stack ([hidden email]:mapping.git): SACModelOrientation in pcl_ias_sample_consensus. It needs points with normals and an axis, and gives the direction which form a coordinate system with the specified axis (and their cross product) and has most point normals aligned with the lines defined by the coordinate system. (It is meant to be put in a second sacmodel that finds the best axis as well and the oriented bounding box, but it is not in PCL yet). However you want to use it on a convex hull to find the encompassing rectangle. I used it for that as well, back in the day of point_cloud_mapping, so the code has to be rewritten. It is not too complicated so I am sure you can do it where you need it. Here are the steps: 1) Create a point cloud that has XYZ coordinates and normals (pcl::PointNormal). 2) Fill in the convex hull points as its points 3) The normals have to be computed as the normalized cross product between the plane normal and the line connecting this point to one of its neighbors (or the normalized sum of the cross products with the two neighboring lines if you prefer). Alternatively, you can create the normals separately and merge it with the points of the contour. Now you can use the SaC fitting of the orientation model to get the optimal direction (the fixed axis being the plane normal), compute the cross product with the axis and check the maximal extends along those directions. If your contour is roughly rectangular it works nicely. I used it for drawing boxes around tables, so I included the points twice, with the same normal, but the Z coordinates set to 0 in the second copy, and it worked nicely :) Maybe Radu can tell if there should be a class that does all this... This turned out rather long, so I'll stop here, but let me know if something is not working. Cheers, Zoltan On Tue, 20101228 at 15:59 +0100, Markus Eich wrote: > Dear all, > > given a convex hull of a plane (by using the nice pcl::ConvexHull2D ;) > I want to calculate the minimum bounding 2D rectangle for the 3D points > > This could be done e.g. using the rotating calipers method. Isn't there > something already available in the PCL for the lazy people ;) > > > Cheers and Happy Holidays > > > Markus > > > _______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
> ([hidden email]:mapping.git): SACModelOrientation in
In case that about url does not work, try out the following one: http://code.in.tum.de/git/mapping.git D. _______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
In reply to this post by Markus Eich
Hey Markus,
If you want to have something quick and dirty I have some code for you. You can use a function in openCV called: cv::minAreaRect(). This function does basically exactly what you want. The crux is, the function works on 2D points, which means you have to do some projecting before using the function. What I did basically was, projecting the points onto a 3D plane, then projecting the 3D plane points onto a 2D plane. I attach the code, but it is certainly not how it should be done. I always wanted to write a function which does this in a proper way, but I didn't have time yet. std::vector<Eigen3::Vector3f> Utilities::fitTableTopBbx(pcl::PointCloud<Point>::ConstPtr &cloud) { std::vector<Eigen3::Vector3f> table_top_bbx; // Project points onto the table plane pcl::ProjectInliers<Point> proj; proj.setModelType(pcl::SACMODEL_PLANE); pcl::PointCloud<Point> projected_cloud; proj.setInputCloud(cloud); proj.setModelCoefficients(table_coefficients_const_); proj.filter(projected_cloud); // store the table top plane parameters Eigen3::Vector3f plane_normal; plane_normal.x() = table_coefficients_const_>values[0]; plane_normal.y() = table_coefficients_const_>values[1]; plane_normal.z() = table_coefficients_const_>values[2]; // compute an orthogonal normal to the plane normal Eigen3::Vector3f v = plane_normal.unitOrthogonal(); // take the cross product of the two normals to get // a thirds normal, on the plane Eigen3::Vector3f u = plane_normal.cross(v); // project the 3D point onto a 2D plane std::vector<cv::Point2f> points; // choose a point on the plane Eigen3::Vector3f p0(projected_cloud.points[0].x, projected_cloud.points[0].y, projected_cloud.points[0].z); for(unsigned int ii=0; ii<projected_cloud.points.size(); ii++) { Eigen3::Vector3f p3d(projected_cloud.points[ii].x, projected_cloud.points[ii].y, projected_cloud.points[ii].z); // subtract all 3D points with a point in the plane // this will move the origin of the 3D coordinate system // onto the plane p3d = p3d  p0; cv::Point2f p2d; p2d.x = p3d.dot(u); p2d.y = p3d.dot(v); points.push_back(p2d); } cv::Mat points_mat(points); cv::RotatedRect rrect = cv::minAreaRect(points_mat); cv::Point2f rrPts[4]; rrect.points(rrPts); //store the table top bounding points in a vector for(unsigned int ii=0; ii<4; ii++) { Eigen3::Vector3f pbbx(rrPts[ii].x*u + rrPts[ii].y*v + p0); table_top_bbx.push_back(pbbx); } Eigen3::Vector3f center(rrect.center.x*u + rrect.center.y*v + p0); table_top_bbx.push_back(center); return table_top_bbx; } Happy Holidays! Cheers Christian On Tue, 20101228 at 15:59 +0100, Markus Eich wrote: > Dear all, > > given a convex hull of a plane (by using the nice pcl::ConvexHull2D ;) > I want to calculate the minimum bounding 2D rectangle for the 3D points > > This could be done e.g. using the rotating calipers method. Isn't there > something already available in the PCL for the lazy people ;) > > > Cheers and Happy Holidays > > > Markus > > > _______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
Thank you all for the comments, I will give it a try.
Cheers, Markus On 28.12.2010 19:16, Christian Potthast wrote: > Hey Markus, > If you want to have something quick and dirty I have some code for you. > You can use a function in openCV called: cv::minAreaRect(). > This function does basically exactly what you want. The crux is, the > function works on 2D points, which means you have to do some projecting > before using the function. > > What I did basically was, projecting the points onto a 3D plane, then > projecting the 3D plane points onto a 2D plane. > > I attach the code, but it is certainly not how it should be done. I > always wanted to write a function which does this in a proper way, but I > didn't have time yet. > > > > std::vector<Eigen3::Vector3f> > Utilities::fitTableTopBbx(pcl::PointCloud<Point>::ConstPtr&cloud) > { > std::vector<Eigen3::Vector3f> table_top_bbx; > > // Project points onto the table plane > pcl::ProjectInliers<Point> proj; > proj.setModelType(pcl::SACMODEL_PLANE); > pcl::PointCloud<Point> projected_cloud; > proj.setInputCloud(cloud); > proj.setModelCoefficients(table_coefficients_const_); > proj.filter(projected_cloud); > > // store the table top plane parameters > Eigen3::Vector3f plane_normal; > plane_normal.x() = table_coefficients_const_>values[0]; > plane_normal.y() = table_coefficients_const_>values[1]; > plane_normal.z() = table_coefficients_const_>values[2]; > // compute an orthogonal normal to the plane normal > Eigen3::Vector3f v = plane_normal.unitOrthogonal(); > // take the cross product of the two normals to get > // a thirds normal, on the plane > Eigen3::Vector3f u = plane_normal.cross(v); > > // project the 3D point onto a 2D plane > std::vector<cv::Point2f> points; > // choose a point on the plane > Eigen3::Vector3f p0(projected_cloud.points[0].x, > projected_cloud.points[0].y, > projected_cloud.points[0].z); > for(unsigned int ii=0; ii<projected_cloud.points.size(); ii++) > { > Eigen3::Vector3f p3d(projected_cloud.points[ii].x, > projected_cloud.points[ii].y, > projected_cloud.points[ii].z); > > // subtract all 3D points with a point in the plane > // this will move the origin of the 3D coordinate system > // onto the plane > p3d = p3d  p0; > > cv::Point2f p2d; > p2d.x = p3d.dot(u); > p2d.y = p3d.dot(v); > points.push_back(p2d); > } > > cv::Mat points_mat(points); > cv::RotatedRect rrect = cv::minAreaRect(points_mat); > cv::Point2f rrPts[4]; > rrect.points(rrPts); > > //store the table top bounding points in a vector > for(unsigned int ii=0; ii<4; ii++) > { > Eigen3::Vector3f pbbx(rrPts[ii].x*u + rrPts[ii].y*v + p0); > table_top_bbx.push_back(pbbx); > } > Eigen3::Vector3f center(rrect.center.x*u + rrect.center.y*v + p0); > table_top_bbx.push_back(center); > > return table_top_bbx; > } > > > Happy Holidays! > > Cheers > Christian > > > > On Tue, 20101228 at 15:59 +0100, Markus Eich wrote: >> Dear all, >> >> given a convex hull of a plane (by using the nice pcl::ConvexHull2D ;) >> I want to calculate the minimum bounding 2D rectangle for the 3D points >> >> This could be done e.g. using the rotating calipers method. Isn't there >> something already available in the PCL for the lazy people ;) >> >> >> Cheers and Happy Holidays >> >> >> Markus >> >> >> > > _______________________________________________ > [hidden email] / http://pointclouds.org > https://code.ros.org/mailman/listinfo/pclusers  Dipl. Inf. Markus Eich Researcher DFKI Bremen Robotics Innovation Center MarySomervilleStr. 9 28359 Bremen, Germany Phone: +49 (0)421 178454105 Fax: +49 (0)421 178454150 EMail: [hidden email] Weitere Informationen: http://www.dfki.de/robotik  Deutsches Forschungszentrum fuer Kuenstliche Intelligenz GmbH Firmensitz: Trippstadter Straße 122, D67663 Kaiserslautern Geschaeftsfuehrung: Prof. Dr. Dr. h.c. mult. Wolfgang Wahlster (Vorsitzender) Dr. Walter Olthoff Vorsitzender des Aufsichtsrats: Prof. Dr. h.c. Hans A. Aukes Amtsgericht Kaiserslautern, HRB 2313 Sitz der Gesellschaft: Kaiserslautern (HRB 2313) UStId.Nr.: DE 148646973 Steuernummer: 19/673/0060/3  _______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
Administrator

Guys,
It would be good to actually get this as a contribution back  I assume this thing will pop up sooner or later again, and having an efficient 3D implementation would be great. :) Cheers, Radu.  http://pointclouds.org On 12/29/2010 01:07 AM, Markus Eich wrote: > Thank you all for the comments, I will give it a try. > > Cheers, > > Markus > > On 28.12.2010 19:16, Christian Potthast wrote: >> Hey Markus, >> If you want to have something quick and dirty I have some code for you. >> You can use a function in openCV called: cv::minAreaRect(). >> This function does basically exactly what you want. The crux is, the >> function works on 2D points, which means you have to do some projecting >> before using the function. >> >> What I did basically was, projecting the points onto a 3D plane, then >> projecting the 3D plane points onto a 2D plane. >> >> I attach the code, but it is certainly not how it should be done. I >> always wanted to write a function which does this in a proper way, but I >> didn't have time yet. >> >> >> >> std::vector<Eigen3::Vector3f> >> Utilities::fitTableTopBbx(pcl::PointCloud<Point>::ConstPtr&cloud) >> { >> std::vector<Eigen3::Vector3f> table_top_bbx; >> >> // Project points onto the table plane >> pcl::ProjectInliers<Point> proj; >> proj.setModelType(pcl::SACMODEL_PLANE); >> pcl::PointCloud<Point> projected_cloud; >> proj.setInputCloud(cloud); >> proj.setModelCoefficients(table_coefficients_const_); >> proj.filter(projected_cloud); >> >> // store the table top plane parameters >> Eigen3::Vector3f plane_normal; >> plane_normal.x() = table_coefficients_const_>values[0]; >> plane_normal.y() = table_coefficients_const_>values[1]; >> plane_normal.z() = table_coefficients_const_>values[2]; >> // compute an orthogonal normal to the plane normal >> Eigen3::Vector3f v = plane_normal.unitOrthogonal(); >> // take the cross product of the two normals to get >> // a thirds normal, on the plane >> Eigen3::Vector3f u = plane_normal.cross(v); >> >> // project the 3D point onto a 2D plane >> std::vector<cv::Point2f> points; >> // choose a point on the plane >> Eigen3::Vector3f p0(projected_cloud.points[0].x, >> projected_cloud.points[0].y, >> projected_cloud.points[0].z); >> for(unsigned int ii=0; ii<projected_cloud.points.size(); ii++) >> { >> Eigen3::Vector3f p3d(projected_cloud.points[ii].x, >> projected_cloud.points[ii].y, >> projected_cloud.points[ii].z); >> >> // subtract all 3D points with a point in the plane >> // this will move the origin of the 3D coordinate system >> // onto the plane >> p3d = p3d  p0; >> >> cv::Point2f p2d; >> p2d.x = p3d.dot(u); >> p2d.y = p3d.dot(v); >> points.push_back(p2d); >> } >> >> cv::Mat points_mat(points); >> cv::RotatedRect rrect = cv::minAreaRect(points_mat); >> cv::Point2f rrPts[4]; >> rrect.points(rrPts); >> >> //store the table top bounding points in a vector >> for(unsigned int ii=0; ii<4; ii++) >> { >> Eigen3::Vector3f pbbx(rrPts[ii].x*u + rrPts[ii].y*v + p0); >> table_top_bbx.push_back(pbbx); >> } >> Eigen3::Vector3f center(rrect.center.x*u + rrect.center.y*v + p0); >> table_top_bbx.push_back(center); >> >> return table_top_bbx; >> } >> >> >> Happy Holidays! >> >> Cheers >> Christian >> >> >> >> On Tue, 20101228 at 15:59 +0100, Markus Eich wrote: >>> Dear all, >>> >>> given a convex hull of a plane (by using the nice pcl::ConvexHull2D ;) >>> I want to calculate the minimum bounding 2D rectangle for the 3D points >>> >>> This could be done e.g. using the rotating calipers method. Isn't there >>> something already available in the PCL for the lazy people ;) >>> >>> >>> Cheers and Happy Holidays >>> >>> >>> Markus >>> >>> >>> >> >> _______________________________________________ >> [hidden email] / http://pointclouds.org >> https://code.ros.org/mailman/listinfo/pclusers > > [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
Hi,
you're right, but we should maybe discuss the method (and interface) to be used. Does anyone have some preference? I guess the openCV function is the most optimal, it just has to be adapted to point clouds. Cheers, Zoltan On Wed, 20101229 at 01:21 0800, Radu Bogdan Rusu wrote: > Guys, > > It would be good to actually get this as a contribution back  I assume this thing will pop up sooner or later again, > and having an efficient 3D implementation would be great. :) > > Cheers, > Radu. >  > http://pointclouds.org > > On 12/29/2010 01:07 AM, Markus Eich wrote: > > Thank you all for the comments, I will give it a try. > > > > Cheers, > > > > Markus > > > > On 28.12.2010 19:16, Christian Potthast wrote: > >> Hey Markus, > >> If you want to have something quick and dirty I have some code for you. > >> You can use a function in openCV called: cv::minAreaRect(). > >> This function does basically exactly what you want. The crux is, the > >> function works on 2D points, which means you have to do some projecting > >> before using the function. > >> > >> What I did basically was, projecting the points onto a 3D plane, then > >> projecting the 3D plane points onto a 2D plane. > >> > >> I attach the code, but it is certainly not how it should be done. I > >> always wanted to write a function which does this in a proper way, but I > >> didn't have time yet. > >> > >> > >> > >> std::vector<Eigen3::Vector3f> > >> Utilities::fitTableTopBbx(pcl::PointCloud<Point>::ConstPtr&cloud) > >> { > >> std::vector<Eigen3::Vector3f> table_top_bbx; > >> > >> // Project points onto the table plane > >> pcl::ProjectInliers<Point> proj; > >> proj.setModelType(pcl::SACMODEL_PLANE); > >> pcl::PointCloud<Point> projected_cloud; > >> proj.setInputCloud(cloud); > >> proj.setModelCoefficients(table_coefficients_const_); > >> proj.filter(projected_cloud); > >> > >> // store the table top plane parameters > >> Eigen3::Vector3f plane_normal; > >> plane_normal.x() = table_coefficients_const_>values[0]; > >> plane_normal.y() = table_coefficients_const_>values[1]; > >> plane_normal.z() = table_coefficients_const_>values[2]; > >> // compute an orthogonal normal to the plane normal > >> Eigen3::Vector3f v = plane_normal.unitOrthogonal(); > >> // take the cross product of the two normals to get > >> // a thirds normal, on the plane > >> Eigen3::Vector3f u = plane_normal.cross(v); > >> > >> // project the 3D point onto a 2D plane > >> std::vector<cv::Point2f> points; > >> // choose a point on the plane > >> Eigen3::Vector3f p0(projected_cloud.points[0].x, > >> projected_cloud.points[0].y, > >> projected_cloud.points[0].z); > >> for(unsigned int ii=0; ii<projected_cloud.points.size(); ii++) > >> { > >> Eigen3::Vector3f p3d(projected_cloud.points[ii].x, > >> projected_cloud.points[ii].y, > >> projected_cloud.points[ii].z); > >> > >> // subtract all 3D points with a point in the plane > >> // this will move the origin of the 3D coordinate system > >> // onto the plane > >> p3d = p3d  p0; > >> > >> cv::Point2f p2d; > >> p2d.x = p3d.dot(u); > >> p2d.y = p3d.dot(v); > >> points.push_back(p2d); > >> } > >> > >> cv::Mat points_mat(points); > >> cv::RotatedRect rrect = cv::minAreaRect(points_mat); > >> cv::Point2f rrPts[4]; > >> rrect.points(rrPts); > >> > >> //store the table top bounding points in a vector > >> for(unsigned int ii=0; ii<4; ii++) > >> { > >> Eigen3::Vector3f pbbx(rrPts[ii].x*u + rrPts[ii].y*v + p0); > >> table_top_bbx.push_back(pbbx); > >> } > >> Eigen3::Vector3f center(rrect.center.x*u + rrect.center.y*v + p0); > >> table_top_bbx.push_back(center); > >> > >> return table_top_bbx; > >> } > >> > >> > >> Happy Holidays! > >> > >> Cheers > >> Christian > >> > >> > >> > >> On Tue, 20101228 at 15:59 +0100, Markus Eich wrote: > >>> Dear all, > >>> > >>> given a convex hull of a plane (by using the nice pcl::ConvexHull2D ;) > >>> I want to calculate the minimum bounding 2D rectangle for the 3D points > >>> > >>> This could be done e.g. using the rotating calipers method. Isn't there > >>> something already available in the PCL for the lazy people ;) > >>> > >>> > >>> Cheers and Happy Holidays > >>> > >>> > >>> Markus > >>> > >>> > >>> > >> > >> _______________________________________________ > >> [hidden email] / http://pointclouds.org > >> https://code.ros.org/mailman/listinfo/pclusers > > > > > _______________________________________________ > [hidden email] / http://pointclouds.org > https://code.ros.org/mailman/listinfo/pclusers _______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
I just used the code Christian send around.
(projecting 3D convex hull into 2D, Do the openCV minAreaFunction, Reproject into 3D). Worked out of the box for me. I just converted the data typ to use PC2 instead of std::vector<Eigen3::Vector3f>. Good thing about 3D>2D projection: Some shape analysis based on openCV can be done right away (e.g. moment invariants, rectangulareness, etc..) Best, Markus On 29.12.2010 16:58, ZoltanCsaba Marton wrote: > Hi, > > you're right, but we should maybe discuss the method (and interface) to > be used. Does anyone have some preference? I guess the openCV function > is the most optimal, it just has to be adapted to point clouds. > > Cheers, > Zoltan > > On Wed, 20101229 at 01:21 0800, Radu Bogdan Rusu wrote: >> Guys, >> >> It would be good to actually get this as a contribution back  I assume this thing will pop up sooner or later again, >> and having an efficient 3D implementation would be great. :) >> >> Cheers, >> Radu. >>  >> http://pointclouds.org >> >> On 12/29/2010 01:07 AM, Markus Eich wrote: >>> Thank you all for the comments, I will give it a try. >>> >>> Cheers, >>> >>> Markus >>> >>> On 28.12.2010 19:16, Christian Potthast wrote: >>>> Hey Markus, >>>> If you want to have something quick and dirty I have some code for you. >>>> You can use a function in openCV called: cv::minAreaRect(). >>>> This function does basically exactly what you want. The crux is, the >>>> function works on 2D points, which means you have to do some projecting >>>> before using the function. >>>> >>>> What I did basically was, projecting the points onto a 3D plane, then >>>> projecting the 3D plane points onto a 2D plane. >>>> >>>> I attach the code, but it is certainly not how it should be done. I >>>> always wanted to write a function which does this in a proper way, but I >>>> didn't have time yet. >>>> >>>> >>>> >>>> std::vector<Eigen3::Vector3f> >>>> Utilities::fitTableTopBbx(pcl::PointCloud<Point>::ConstPtr&cloud) >>>> { >>>> std::vector<Eigen3::Vector3f> table_top_bbx; >>>> >>>> // Project points onto the table plane >>>> pcl::ProjectInliers<Point> proj; >>>> proj.setModelType(pcl::SACMODEL_PLANE); >>>> pcl::PointCloud<Point> projected_cloud; >>>> proj.setInputCloud(cloud); >>>> proj.setModelCoefficients(table_coefficients_const_); >>>> proj.filter(projected_cloud); >>>> >>>> // store the table top plane parameters >>>> Eigen3::Vector3f plane_normal; >>>> plane_normal.x() = table_coefficients_const_>values[0]; >>>> plane_normal.y() = table_coefficients_const_>values[1]; >>>> plane_normal.z() = table_coefficients_const_>values[2]; >>>> // compute an orthogonal normal to the plane normal >>>> Eigen3::Vector3f v = plane_normal.unitOrthogonal(); >>>> // take the cross product of the two normals to get >>>> // a thirds normal, on the plane >>>> Eigen3::Vector3f u = plane_normal.cross(v); >>>> >>>> // project the 3D point onto a 2D plane >>>> std::vector<cv::Point2f> points; >>>> // choose a point on the plane >>>> Eigen3::Vector3f p0(projected_cloud.points[0].x, >>>> projected_cloud.points[0].y, >>>> projected_cloud.points[0].z); >>>> for(unsigned int ii=0; ii<projected_cloud.points.size(); ii++) >>>> { >>>> Eigen3::Vector3f p3d(projected_cloud.points[ii].x, >>>> projected_cloud.points[ii].y, >>>> projected_cloud.points[ii].z); >>>> >>>> // subtract all 3D points with a point in the plane >>>> // this will move the origin of the 3D coordinate system >>>> // onto the plane >>>> p3d = p3d  p0; >>>> >>>> cv::Point2f p2d; >>>> p2d.x = p3d.dot(u); >>>> p2d.y = p3d.dot(v); >>>> points.push_back(p2d); >>>> } >>>> >>>> cv::Mat points_mat(points); >>>> cv::RotatedRect rrect = cv::minAreaRect(points_mat); >>>> cv::Point2f rrPts[4]; >>>> rrect.points(rrPts); >>>> >>>> //store the table top bounding points in a vector >>>> for(unsigned int ii=0; ii<4; ii++) >>>> { >>>> Eigen3::Vector3f pbbx(rrPts[ii].x*u + rrPts[ii].y*v + p0); >>>> table_top_bbx.push_back(pbbx); >>>> } >>>> Eigen3::Vector3f center(rrect.center.x*u + rrect.center.y*v + p0); >>>> table_top_bbx.push_back(center); >>>> >>>> return table_top_bbx; >>>> } >>>> >>>> >>>> Happy Holidays! >>>> >>>> Cheers >>>> Christian >>>> >>>> >>>> >>>> On Tue, 20101228 at 15:59 +0100, Markus Eich wrote: >>>>> Dear all, >>>>> >>>>> given a convex hull of a plane (by using the nice pcl::ConvexHull2D ;) >>>>> I want to calculate the minimum bounding 2D rectangle for the 3D points >>>>> >>>>> This could be done e.g. using the rotating calipers method. Isn't there >>>>> something already available in the PCL for the lazy people ;) >>>>> >>>>> >>>>> Cheers and Happy Holidays >>>>> >>>>> >>>>> Markus >>>>> >>>>> >>>>> >>>> _______________________________________________ >>>> [hidden email] / http://pointclouds.org >>>> https://code.ros.org/mailman/listinfo/pclusers >>> >> _______________________________________________ >> [hidden email] / http://pointclouds.org >> https://code.ros.org/mailman/listinfo/pclusers > > > _______________________________________________ > [hidden email] / http://pointclouds.org > https://code.ros.org/mailman/listinfo/pclusers  Dipl. Inf. Markus Eich Researcher DFKI Bremen Robotics Innovation Center MarySomervilleStr. 9 28359 Bremen, Germany Phone: +49 (0)421 178454105 Fax: +49 (0)421 178454150 EMail: [hidden email] Weitere Informationen: http://www.dfki.de/robotik  Deutsches Forschungszentrum fuer Kuenstliche Intelligenz GmbH Firmensitz: Trippstadter Straße 122, D67663 Kaiserslautern Geschaeftsfuehrung: Prof. Dr. Dr. h.c. mult. Wolfgang Wahlster (Vorsitzender) Dr. Walter Olthoff Vorsitzender des Aufsichtsrats: Prof. Dr. h.c. Hans A. Aukes Amtsgericht Kaiserslautern, HRB 2313 Sitz der Gesellschaft: Kaiserslautern (HRB 2313) UStId.Nr.: DE 148646973 Steuernummer: 19/673/0060/3  _______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
Administrator

That's fair. I should have said why we would prefer an efficient 3D method instead. One of the goals for 1.0 is to get
PCL to be 100% CUDA accelerated. The project hasn't started yet, and that's why we haven't begun discussing the details on the mailing list, but we will soon :) If the minAreaFunction operator is something that will pop up again, writing a standalone function that operates on 3D data might make it easier to port it to the GPU (and also allow us to have an efficient SSEpadded optimization on the CPU). Cheers, Radu.  http://pointclouds.org On 12/29/2010 08:10 AM, Markus Eich wrote: > I just used the code Christian send around. > > (projecting 3D convex hull into 2D, Do the openCV minAreaFunction, > Reproject into 3D). > > Worked out of the box for me. I just converted the data typ to use PC2 > instead of std::vector<Eigen3::Vector3f>. > > Good thing about 3D>2D projection: Some shape analysis based on openCV > can be done right away (e.g. moment invariants, rectangulareness, etc..) > > Best, > > Markus > > > On 29.12.2010 16:58, ZoltanCsaba Marton wrote: >> Hi, >> >> you're right, but we should maybe discuss the method (and interface) to >> be used. Does anyone have some preference? I guess the openCV function >> is the most optimal, it just has to be adapted to point clouds. >> >> Cheers, >> Zoltan >> >> On Wed, 20101229 at 01:21 0800, Radu Bogdan Rusu wrote: >>> Guys, >>> >>> It would be good to actually get this as a contribution back  I assume this thing will pop up sooner or later again, >>> and having an efficient 3D implementation would be great. :) >>> >>> Cheers, >>> Radu. >>>  >>> http://pointclouds.org >>> >>> On 12/29/2010 01:07 AM, Markus Eich wrote: >>>> Thank you all for the comments, I will give it a try. >>>> >>>> Cheers, >>>> >>>> Markus >>>> >>>> On 28.12.2010 19:16, Christian Potthast wrote: >>>>> Hey Markus, >>>>> If you want to have something quick and dirty I have some code for you. >>>>> You can use a function in openCV called: cv::minAreaRect(). >>>>> This function does basically exactly what you want. The crux is, the >>>>> function works on 2D points, which means you have to do some projecting >>>>> before using the function. >>>>> >>>>> What I did basically was, projecting the points onto a 3D plane, then >>>>> projecting the 3D plane points onto a 2D plane. >>>>> >>>>> I attach the code, but it is certainly not how it should be done. I >>>>> always wanted to write a function which does this in a proper way, but I >>>>> didn't have time yet. >>>>> >>>>> >>>>> >>>>> std::vector<Eigen3::Vector3f> >>>>> Utilities::fitTableTopBbx(pcl::PointCloud<Point>::ConstPtr&cloud) >>>>> { >>>>> std::vector<Eigen3::Vector3f> table_top_bbx; >>>>> >>>>> // Project points onto the table plane >>>>> pcl::ProjectInliers<Point> proj; >>>>> proj.setModelType(pcl::SACMODEL_PLANE); >>>>> pcl::PointCloud<Point> projected_cloud; >>>>> proj.setInputCloud(cloud); >>>>> proj.setModelCoefficients(table_coefficients_const_); >>>>> proj.filter(projected_cloud); >>>>> >>>>> // store the table top plane parameters >>>>> Eigen3::Vector3f plane_normal; >>>>> plane_normal.x() = table_coefficients_const_>values[0]; >>>>> plane_normal.y() = table_coefficients_const_>values[1]; >>>>> plane_normal.z() = table_coefficients_const_>values[2]; >>>>> // compute an orthogonal normal to the plane normal >>>>> Eigen3::Vector3f v = plane_normal.unitOrthogonal(); >>>>> // take the cross product of the two normals to get >>>>> // a thirds normal, on the plane >>>>> Eigen3::Vector3f u = plane_normal.cross(v); >>>>> >>>>> // project the 3D point onto a 2D plane >>>>> std::vector<cv::Point2f> points; >>>>> // choose a point on the plane >>>>> Eigen3::Vector3f p0(projected_cloud.points[0].x, >>>>> projected_cloud.points[0].y, >>>>> projected_cloud.points[0].z); >>>>> for(unsigned int ii=0; ii<projected_cloud.points.size(); ii++) >>>>> { >>>>> Eigen3::Vector3f p3d(projected_cloud.points[ii].x, >>>>> projected_cloud.points[ii].y, >>>>> projected_cloud.points[ii].z); >>>>> >>>>> // subtract all 3D points with a point in the plane >>>>> // this will move the origin of the 3D coordinate system >>>>> // onto the plane >>>>> p3d = p3d  p0; >>>>> >>>>> cv::Point2f p2d; >>>>> p2d.x = p3d.dot(u); >>>>> p2d.y = p3d.dot(v); >>>>> points.push_back(p2d); >>>>> } >>>>> >>>>> cv::Mat points_mat(points); >>>>> cv::RotatedRect rrect = cv::minAreaRect(points_mat); >>>>> cv::Point2f rrPts[4]; >>>>> rrect.points(rrPts); >>>>> >>>>> //store the table top bounding points in a vector >>>>> for(unsigned int ii=0; ii<4; ii++) >>>>> { >>>>> Eigen3::Vector3f pbbx(rrPts[ii].x*u + rrPts[ii].y*v + p0); >>>>> table_top_bbx.push_back(pbbx); >>>>> } >>>>> Eigen3::Vector3f center(rrect.center.x*u + rrect.center.y*v + p0); >>>>> table_top_bbx.push_back(center); >>>>> >>>>> return table_top_bbx; >>>>> } >>>>> >>>>> >>>>> Happy Holidays! >>>>> >>>>> Cheers >>>>> Christian >>>>> >>>>> >>>>> >>>>> On Tue, 20101228 at 15:59 +0100, Markus Eich wrote: >>>>>> Dear all, >>>>>> >>>>>> given a convex hull of a plane (by using the nice pcl::ConvexHull2D ;) >>>>>> I want to calculate the minimum bounding 2D rectangle for the 3D points >>>>>> >>>>>> This could be done e.g. using the rotating calipers method. Isn't there >>>>>> something already available in the PCL for the lazy people ;) >>>>>> >>>>>> >>>>>> Cheers and Happy Holidays >>>>>> >>>>>> >>>>>> Markus >>>>>> >>>>>> >>>>>> >>>>> _______________________________________________ >>>>> [hidden email] / http://pointclouds.org >>>>> https://code.ros.org/mailman/listinfo/pclusers >>>> >>> _______________________________________________ >>> [hidden email] / http://pointclouds.org >>> https://code.ros.org/mailman/listinfo/pclusers >> >> >> _______________________________________________ >> [hidden email] / http://pointclouds.org >> https://code.ros.org/mailman/listinfo/pclusers > > [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
Hi,
it's off topic but I'm curious why do you promote CUDA, instead of vendor independent standards like OpenCL ? Pozdrawiam Konrad Banachowicz 2010/12/29 Radu Bogdan Rusu <[hidden email]> That's fair. I should have said why we would prefer an efficient 3D method instead. One of the goals for 1.0 is to get _______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
Administrator

We'll probably do both and let users test and use what's best for them. Cheers,
_______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
FYI, I was recently playing around with CUDA opencv on my Mac, and despite my nvidia card, I couldn't get it to work because the npp libraries are 32 bit only (ie useless) on osx.
_______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
As far as i know OpenCL is very well supported on OSX. You can find some OpenCL image processing code here : https://github.com/mateuszpruchniak/gpuprocessor
Pozdrawiam Konrad Banachowicz 2010/12/30 Nicholas Butko <[hidden email]>
_______________________________________________ [hidden email] / http://pointclouds.org https://code.ros.org/mailman/listinfo/pclusers 
Has a native PCL solution to this problem been resolved?

I wrote some PCLbased (does not use OpenCV) code to do this just last week, based in the rotating calipers method and working in 3D with the assumption that the convex hull has already been previously projected. Code itself was mainly based on the description in [1] and the R implementation in whuber's answer of [2]. It should not be very hard to generalize the code to be included in PCL but I have no experience doing that. If someone would be willing to walk me through the process (baby steps) that'd be great. [1]  https://geidav.wordpress.com/2014/01/23/computingorientedminimumboundingboxesin2d/ [2]  http://gis.stackexchange.com/questions/22895/howtofindtheminimumarearectangleforgivenpoints 
Administrator

Hello,
If you want to contribute to PCL, take a look at CONTRIBUTING.md. All you have to do is to propose a pull request against PCL master branch via GitHub. If you're not familiar with this; I suggest reading this: https://github.com/PointCloudLibrary/pcl/wiki/Astepbystepguideonpreparingandsubmittingapullrequest Do not hesitate if you have further questions! Bye 
Hi Victor,
On Wed, Apr 15, 2015 at 3:15 PM, VictorL <[hidden email]> wrote: > Hello, > > If you want to contribute to PCL, take a look at CONTRIBUTING.md > <https://github.com/PointCloudLibrary/pcl/blob/master/CONTRIBUTING.md> Yep, I've seen this before, but the constraints of my current employment (primarily time constraints) have precluded actually contributing. Writing code is a whole lot faster than writing properly structured code for PCL, as I'm sure you know =). It's on my (long) todo list. However, would such code be useful/accepted? I haven't found any guidelines on what would be considered relevant to be accepted and what wouldn't. _______________________________________________ [hidden email] / http://pointclouds.org http://pointclouds.org/mailman/listinfo/pclusers 
Administrator

Given the number of posts in this topic it is clearly an interesting feature!
It will be accepted as soon as the code respects the PCL sytle guide and it's approved by the PCL staff on GitHub. 
This post has NOT been accepted by the mailing list yet.
In reply to this post by ngoonee
While you get round to contributing a clean version ngoone, would you mind sharing your function? It might be that someone else with a bit more time will be able to add it (with appropriate credit of course) and in the mean time those in need (like myself) can use what you already have.
Thanks in advance, Seb

Free forum by Nabble  Edit this page 