35 #define BOOST_PARAMETER_MAX_ARITY 7 
   37 #include <opencv2/opencv.hpp> 
   45     DiagnosticNodelet::onInit();
 
   47       *pnh_, 
"debug/min_area_rect_image", 1);
 
   67     sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
 
   80     const sensor_msgs::Image::ConstPtr& image_msg,
 
   81     const sensor_msgs::CameraInfo::ConstPtr& info_msg,
 
   82     const pcl_msgs::ModelCoefficients::ConstPtr& polygon_3d_coefficient_msg)
 
   87     pcl::ModelCoefficients::Ptr polygon_coefficients
 
   88       (
new pcl::ModelCoefficients);
 
   93     std::vector<cv::Point> all_points;
 
   94     for (
int j = 0; j < object_image.rows; j++) {
 
   95       for (
int i = 0; 
i < object_image.cols; 
i++) {
 
   96         if (object_image.at<uchar>(j, 
i) == 255) {
 
   97           all_points.push_back(cv::Point(
i, j));
 
  101     cv::RotatedRect obb = cv::minAreaRect(all_points);
 
  103     cv::Mat min_area_rect_image;
 
  104     cv::cvtColor(object_image, min_area_rect_image, CV_GRAY2BGR);
 
  105     cv::Point2f vertices2f[4];
 
  106     obb.points(vertices2f);
 
  107     cv::line(min_area_rect_image, vertices2f[0], vertices2f[1],
 
  108              cv::Scalar(0, 0, 255), 4);
 
  109     cv::line(min_area_rect_image, vertices2f[1], vertices2f[2],
 
  110              cv::Scalar(0, 0, 255), 4);
 
  111     cv::line(min_area_rect_image, vertices2f[2], vertices2f[3],
 
  112              cv::Scalar(0, 0, 255), 4);
 
  113     cv::line(min_area_rect_image, vertices2f[3], vertices2f[0],
 
  114              cv::Scalar(0, 0, 255), 4);
 
  115     cv::Rect bb = obb.boundingRect();
 
  116     std::vector<cv::Point3f> search_points_3d;
 
  117     std::vector<cv::Point2f> search_points_2d;
 
  119                         model, polygon_coefficients,
 
  120                         search_points_3d, search_points_2d);
 
  121     for (
size_t i = 0; 
i < search_points_2d.size(); 
i++) {
 
  122       cv::circle(min_area_rect_image, search_points_2d[
i], 5, cv::Scalar(0, 255, 0), 1);
 
  126     double min_area = DBL_MAX;
 
  128     cv::Point2f min_search_point;
 
  131     for (
size_t i = 0; 
i < search_points_2d.size(); 
i++) {
 
  132       std::vector<double> 
angles;
 
  133       std::vector<double> max_x;
 
  134       std::vector<double> max_y;
 
  139       for (
size_t j = 0; j < 
angles.size(); j++) {
 
  140         double area = 
drawAngle(min_area_rect_image, search_points_2d[
i], 
angles[j],
 
  141                                 max_x[j], max_y[j], 
model, plane, cv::Scalar(0, 255, 0));
 
  142         if (area < min_area) {
 
  147           min_search_point = search_points_2d[
i];
 
  151     drawAngle(min_area_rect_image, min_search_point, min_angle,
 
  152               min_x, min_y, 
model, plane, cv::Scalar(0, 255, 255));
 
  163     const cv::Mat& blob_image, 
const cv::Point2f& test_point,
 
  164     std::vector<double>& 
angles,
 
  165     std::vector<double>& max_x,
 
  166     std::vector<double>& max_y,
 
  171     const double angle_step = 3;
 
  172     std::vector<cv::Point> indices;
 
  173     for (
int j = 0; j < blob_image.rows; j++) {
 
  174         for (
int i = 0; 
i < blob_image.cols; 
i++) {
 
  175           if (blob_image.at<uchar>(j, 
i) != 0) { 
 
  176             indices.push_back(cv::Point(
i, j));
 
  183       cv::Point2d uy_end = 
getUyEnd(test_point, cv::Point2d(test_point.x + ux[0], test_point.y + ux[1]),
 
  186       Eigen::Vector2f uy(uy_end.x - test_point.x, uy_end.y - test_point.y);
 
  191       bool excluded = 
false;
 
  192       double max_alpha = -DBL_MAX;
 
  193       double max_beta = -DBL_MAX;
 
  194       for (
size_t i = 0; 
i < indices.size(); 
i++) {
 
  195         Eigen::Vector2f p_q = Eigen::Vector2f(indices[
i].
x, indices[
i].
y) - Eigen::Vector2f(test_point.x, test_point.y);
 
  196         Eigen::Vector2f a_b = 
A.inverse() * p_q;
 
  197         double alpha = a_b[0];
 
  198         double beta = a_b[1];
 
  199         if (
alpha < 0 || beta < 0) {
 
  203         if (
alpha > max_alpha) {
 
  206         if (beta > max_beta) {
 
  213         max_x.push_back(max_alpha);
 
  214         max_y.push_back(max_beta);
 
  220     const cv::Point3d& ray,
 
  223     Eigen::Vector3f 
n = plane->getNormal();
 
  224     Eigen::Vector3f 
d(ray.x, ray.y, ray.z);
 
  225     double alpha = - plane->getD() / 
n.dot(
d);
 
  230     const cv::Point2d& ux_start,
 
  231     const cv::Point2d& ux_end,
 
  235     cv::Point3d start_ray = 
model.projectPixelTo3dRay(ux_start);
 
  236     cv::Point3d end_ray = 
model.projectPixelTo3dRay(ux_end);
 
  239     Eigen::Vector3f ux_3d = ux_end_3d - ux_start_3d;
 
  240     Eigen::Vector3f normal = plane->getNormal();
 
  241     Eigen::Vector3f uy_3d = normal.cross(ux_3d).normalized();
 
  242     Eigen::Vector3f uy_end_3d = ux_start_3d + uy_3d;
 
  243     cv::Point2d uy_end = 
model.project3dToPixel(cv::Point3d(uy_end_3d[0],
 
  250     cv::Mat& out_image, 
const cv::Point2f& test_point, 
const double angle,
 
  251     const double max_x, 
const double max_y,
 
  258       test_point, cv::Point2d(test_point.x + ux[0], test_point.y + ux[1]),
 
  260     Eigen::Vector2f uy(uy_end.x - test_point.x, uy_end.y - test_point.y);
 
  262     Eigen::Vector2f to_point = ux * max_x + Eigen::Vector2f(test_point.x, test_point.y);
 
  263     Eigen::Vector2f to_point2 = uy * max_y + Eigen::Vector2f(test_point.x, test_point.y);
 
  264     cv::Point2f to_point_cv(to_point[0], to_point[1]);
 
  265     cv::Point2f to_point2_cv(to_point2[0], to_point2[1]);
 
  266     cv::Point2f to_point3_cv = to_point_cv + to_point2_cv - test_point;
 
  267     cv::line(out_image, test_point, to_point_cv, color, 4);
 
  268     cv::line(out_image, test_point, to_point2_cv, color, 4);
 
  269     cv::line(out_image, to_point_cv, to_point3_cv, color, 4);
 
  270     cv::line(out_image, to_point2_cv, to_point3_cv, color, 4);
 
  271     return max_x * max_y;       
 
  275     const cv::Point2f& point_2d,
 
  277     const pcl::ModelCoefficients::Ptr& coefficients,
 
  278     std::vector<cv::Point3f>& search_points_3d,
 
  279     std::vector<cv::Point2f>& search_points_2d)
 
  284     cv::Point3d ray = 
model.projectPixelTo3dRay(point_2d);
 
  286     const double resolution_step = 0.01;
 
  288     search_points_3d.clear();
 
  289     search_points_2d.clear();
 
  292         double x_diff = resolution_step * 
i;
 
  293         double y_diff = resolution_step * j;
 
  294         Eigen::Vector3f moved_point = projected_point + Eigen::Vector3f(x_diff, y_diff, 0);
 
  295         Eigen::Vector3f projected_moved_point;
 
  296         plane->project(moved_point, projected_moved_point);
 
  297         cv::Point3f projected_moved_point_cv(projected_moved_point[0],
 
  298                                              projected_moved_point[1],
 
  299                                              projected_moved_point[2]);
 
  300         search_points_3d.push_back(cv::Point3f(projected_moved_point_cv));
 
  301         cv::Point2d p2d = 
model.project3dToPixel(projected_moved_point_cv);
 
  302         search_points_2d.push_back(p2d);