Minimum Rectangle

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

Minimum Rectangle

Markus Eich
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
Mary-Somerville-Str. 9
28359 Bremen, Germany

Phone: +49 (0)421 17845-4105
Fax:   +49 (0)421 17845-4150
E-Mail: [hidden email]

Weitere Informationen: http://www.dfki.de/robotik
-----------------------------------------------------------------------
Deutsches Forschungszentrum fuer Kuenstliche Intelligenz GmbH
Firmensitz: Trippstadter Straße 122, D-67663 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)
USt-Id.Nr.:    DE 148646973
Steuernummer:  19/673/0060/3
-----------------------------------------------------------------------

_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Zoltan-Csaba Marton
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 sac-model 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 re-written. 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, 2010-12-28 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/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Dejan Pangercic
> ([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/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Christian Potthast
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, 2010-12-28 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/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Markus Eich
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, 2010-12-28 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/pcl-users


--
Dipl. Inf. Markus Eich
Researcher

DFKI Bremen
Robotics Innovation Center
Mary-Somerville-Str. 9
28359 Bremen, Germany

Phone: +49 (0)421 17845-4105
Fax:   +49 (0)421 17845-4150
E-Mail: [hidden email]

Weitere Informationen: http://www.dfki.de/robotik
-----------------------------------------------------------------------
Deutsches Forschungszentrum fuer Kuenstliche Intelligenz GmbH
Firmensitz: Trippstadter Straße 122, D-67663 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)
USt-Id.Nr.:    DE 148646973
Steuernummer:  19/673/0060/3
-----------------------------------------------------------------------

_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Radu B. Rusu
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, 2010-12-28 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/pcl-users
>
>
_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Zoltan-Csaba Marton
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, 2010-12-29 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, 2010-12-28 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/pcl-users
> >
> >
> _______________________________________________
> [hidden email] / http://pointclouds.org
> https://code.ros.org/mailman/listinfo/pcl-users



_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Markus Eich
I just used the code Christian send around.

(projecting 3D convex hull into 2D, Do the openCV minAreaFunction,
Re-project 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, Zoltan-Csaba 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, 2010-12-29 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, 2010-12-28 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/pcl-users
>>>
>> _______________________________________________
>> [hidden email] / http://pointclouds.org
>> https://code.ros.org/mailman/listinfo/pcl-users
>
>
> _______________________________________________
> [hidden email] / http://pointclouds.org
> https://code.ros.org/mailman/listinfo/pcl-users


--
Dipl. Inf. Markus Eich
Researcher

DFKI Bremen
Robotics Innovation Center
Mary-Somerville-Str. 9
28359 Bremen, Germany

Phone: +49 (0)421 17845-4105
Fax:   +49 (0)421 17845-4150
E-Mail: [hidden email]

Weitere Informationen: http://www.dfki.de/robotik
-----------------------------------------------------------------------
Deutsches Forschungszentrum fuer Kuenstliche Intelligenz GmbH
Firmensitz: Trippstadter Straße 122, D-67663 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)
USt-Id.Nr.:    DE 148646973
Steuernummer:  19/673/0060/3
-----------------------------------------------------------------------

_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Radu B. Rusu
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 SSE-padded 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,
> Re-project 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, Zoltan-Csaba 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, 2010-12-29 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, 2010-12-28 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/pcl-users
>>>>
>>> _______________________________________________
>>> [hidden email] / http://pointclouds.org
>>> https://code.ros.org/mailman/listinfo/pcl-users
>>
>>
>> _______________________________________________
>> [hidden email] / http://pointclouds.org
>> https://code.ros.org/mailman/listinfo/pcl-users
>
>
_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Konrad Banachowicz
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
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 SSE-padded 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,
> Re-project 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, Zoltan-Csaba 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, 2010-12-29 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, 2010-12-28 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/pcl-users
>>>>
>>> _______________________________________________
>>> [hidden email] / http://pointclouds.org
>>> https://code.ros.org/mailman/listinfo/pcl-users
>>
>>
>> _______________________________________________
>> [hidden email] / http://pointclouds.org
>> https://code.ros.org/mailman/listinfo/pcl-users
>
>
_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users


_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Radu B. Rusu
Administrator
We'll probably do both and let users test and use what's best for them.

Cheers,
Radu

On Dec 30, 2010, at 2:29, Konrad Banachowicz <[hidden email]> wrote:

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
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 SSE-padded 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,
> Re-project 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, Zoltan-Csaba 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, 2010-12-29 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, 2010-12-28 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/pcl-users
>>>>
>>> _______________________________________________
>>> [hidden email] / http://pointclouds.org
>>> https://code.ros.org/mailman/listinfo/pcl-users
>>
>>
>> _______________________________________________
>> [hidden email] / http://pointclouds.org
>> https://code.ros.org/mailman/listinfo/pcl-users
>
>
_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users


_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Nicholas Butko
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. 



On Dec 30, 2010, at 8:51 AM, Radu Bogdan Rusu <[hidden email]> wrote:

We'll probably do both and let users test and use what's best for them.

Cheers,
Radu

On Dec 30, 2010, at 2:29, Konrad Banachowicz <[hidden email]> wrote:

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][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
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 SSE-padded 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,
> Re-project 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, Zoltan-Csaba 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, 2010-12-29 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, 2010-12-28 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][hidden email] / http://pointclouds.org
>>>>> https://code.ros.org/mailman/listinfo/pcl-users
>>>>
>>> _______________________________________________
>>> [hidden email][hidden email] / http://pointclouds.org
>>> https://code.ros.org/mailman/listinfo/pcl-users
>>
>>
>> _______________________________________________
>> [hidden email][hidden email] / http://pointclouds.org
>> https://code.ros.org/mailman/listinfo/pcl-users
>
>
_______________________________________________
[hidden email][hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users


_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Konrad Banachowicz
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]>
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. 



On Dec 30, 2010, at 8:51 AM, Radu Bogdan Rusu <[hidden email]> wrote:

We'll probably do both and let users test and use what's best for them.

Cheers,
Radu

On Dec 30, 2010, at 2:29, Konrad Banachowicz <[hidden email][hidden email]> wrote:

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][hidden email][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
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 SSE-padded 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,
> Re-project 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, Zoltan-Csaba 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, 2010-12-29 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, 2010-12-28 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][hidden email][hidden email] / http://pointclouds.org
>>>>> https://code.ros.org/mailman/listinfo/pcl-users
>>>>
>>> _______________________________________________
>>> [hidden email][hidden email][hidden email] / http://pointclouds.org
>>> https://code.ros.org/mailman/listinfo/pcl-users
>>
>>
>> _______________________________________________
>> [hidden email][hidden email][hidden email] / http://pointclouds.org
>> https://code.ros.org/mailman/listinfo/pcl-users
>
>
_______________________________________________
[hidden email][hidden email][hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users



_______________________________________________
[hidden email] / http://pointclouds.org
https://code.ros.org/mailman/listinfo/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

BenD
Has a native PCL solution to this problem been resolved?
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

ngoonee
BenD wrote
Has a native PCL solution to this problem been resolved?
I wrote some PCL-based (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/computing-oriented-minimum-bounding-boxes-in-2d/
[2] - http://gis.stackexchange.com/questions/22895/how-to-find-the-minimum-area-rectangle-for-given-points
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

VictorLamoine
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/A-step-by-step-guide-on-preparing-and-submitting-a-pull-request

Do not hesitate if you have further questions!
Bye
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

ngoonee
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) to-do 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/pcl-users
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

VictorLamoine
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.
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

sebandraos
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

ngoonee wrote
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) to-do 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.
Reply | Threaded
Open this post in threaded view
|

Re: Minimum Rectangle

Dan Chen
This post has NOT been accepted by the mailing list yet.
Hi,

Just wonder if this function has been included in current PCL?
Really need this on my recent project :)

Thanks,

Dan