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);