// TODO: This method is only used for planar segmentation, consider removing Box3D minAreaRect(pcl::PointCloud<PointT>::Ptr &input_cloud) { //assuming chull is already sequential, if not we'll need to sort it. It seems like it is. Box3D box; pcl::PointCloud<PointT>::Ptr cloud_hull (new pcl::PointCloud<PointT>); pcl::ConvexHull<PointT> chull; chull.setInputCloud (input_cloud); chull.reconstruct (*cloud_hull); int n = cloud_hull->size(); PointT out[3]; if( n > 2 ) { rotatingCalipers( cloud_hull, n, CALIPERS_MINAREARECT, out ); box.center.x = out[0].x + (out[1].x + out[2].x)*0.5f; box.center.y = out[0].y + (out[1].y + out[2].y)*0.5f; /*box.size.xSize = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y); box.size.ySize = (float)sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y); box.angle = (float)atan2( (double)out[1].y, (double)out[1].x );*/ //xSize always the long! float norm1 = (float)sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y); float norm2 = (float)sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y); if(norm1 > norm2) { box.size.xSize = norm1; box.size.ySize = norm2; //box.angle = (float)atan2( (double)out[1].y, (double)out[1].x );//(float)atan(out[1].y/out[1].x);// } else { box.size.xSize = norm2; box.size.ySize = norm1; //box.angle = (float)atan2( (double)out[2].y, (double)out[2].x ); //(float)atan(out[2].y/out[2].x);// } } //haven't tested the below cases! else if( n == 2 ) { box.center.x = ( cloud_hull->points[0].x + cloud_hull->points[1].x)*0.5f; box.center.y = ( cloud_hull->points[0].y + cloud_hull->points[1].y)*0.5f; double dx = cloud_hull->points[1].x - cloud_hull->points[0].x; double dy = cloud_hull->points[1].y - cloud_hull->points[0].y; box.size.xSize = (float)sqrt(dx*dx + dy*dy); box.size.ySize = 0; //box.angle = (float)atan2( dy, dx ); } else { if( n == 1 ) box.center.x = cloud_hull->points[0].x; box.center.y = cloud_hull->points[0].y; //box.angle = 0; } //box.fillQuatGivenAxisAngle(); return box; }
cv::RotatedRect cv::minAreaRect( InputArray _points ) { Mat hull; Point2f out[3]; RotatedRect box; convexHull(_points, hull, true, true); if( hull.depth() != CV_32F ) { Mat temp; hull.convertTo(temp, CV_32F); hull = temp; } int n = hull.checkVector(2); const Point2f* hpoints = hull.ptr<Point2f>(); if( n > 2 ) { rotatingCalipers( hpoints, n, CALIPERS_MINAREARECT, (float*)out ); box.center.x = out[0].x + (out[1].x + out[2].x)*0.5f; box.center.y = out[0].y + (out[1].y + out[2].y)*0.5f; box.size.width = (float)std::sqrt((double)out[1].x*out[1].x + (double)out[1].y*out[1].y); box.size.height = (float)std::sqrt((double)out[2].x*out[2].x + (double)out[2].y*out[2].y); box.angle = (float)atan2( (double)out[1].y, (double)out[1].x ); } else if( n == 2 ) { box.center.x = (hpoints[0].x + hpoints[1].x)*0.5f; box.center.y = (hpoints[0].y + hpoints[1].y)*0.5f; double dx = hpoints[1].x - hpoints[0].x; double dy = hpoints[1].y - hpoints[0].y; box.size.width = (float)std::sqrt(dx*dx + dy*dy); box.size.height = 0; box.angle = (float)atan2( dy, dx ); } else { if( n == 1 ) box.center = hpoints[0]; } box.angle = (float)(box.angle*180/CV_PI); return box; }