4 #include <opencv2/core/core.hpp>
5 #include <opencv2/imgproc/imgproc.hpp>
7 #include <ros/console.h>
17 static int dx[4] = {1, 0, -1, 0 };
18 static int dy[4] = {0, 1, 0, -1 };
20 unsigned char v =
image.at<
unsigned char>(p.
y, p.
x);
22 int d_current = d_start;
26 int line_piece_min = 1e9;
27 int line_piece_max = 0;
29 int d_main = d_current;
36 int n_uninterrupted = 1;
42 int d = (d_current + 3) % 4;
44 for(
int i = -1; i < 3; ++i)
46 int idx_x = x2 + dx[d];
47 int idx_y = y2 + dy[d];
53 if (idx_y < 0 || idx_y >=
image.rows || idx_x < 0 || idx_x >=
image.cols)
55 ROS_ERROR(
"This should not happen! Image going out of bound, findContours. [%d, %d] and image size is [%d,%d]", idx_y, idx_x,
image.rows,
image.cols);
58 if (
image.at<
unsigned char>(idx_y, idx_x) == v)
72 if ((d + 2) % 4 == d_current)
76 if (x2 == p.
x && y2 == p.
y)
87 else if (d_current != d_main)
113 if (line_piece_max > 0 && (n_uninterrupted < line_piece_max - 2 || n_uninterrupted > line_piece_min + 2))
118 line_piece_min = 1e9;
123 line_piece_min =
std::min(line_piece_min, n_uninterrupted);
124 line_piece_max =
std::max(line_piece_max, n_uninterrupted);
130 p_corner = p_current;
134 if ((d_current == 3 && d != 2) || (d == 3 && d != 0))
137 if (p_current.
y < 0 || p_current.
y >= contour_map.rows || p_current.
x < 0 || p_current.
x >= contour_map.cols)
139 ROS_ERROR(
"This should not happen! Contour map going out of bound, findContours. [%d, %d] and contour map size is [%d,%d]", p_current.
y, p_current.
x, contour_map.rows, contour_map.cols);
142 contour_map.at<
unsigned char>(p_current.
y, p_current.
x) = 1;
146 if (points.
size() > 1 && x2 == p.
x && y2 == p.
y)
160 cv::Mat contour_map(
image.rows,
image.cols, CV_8UC1, cv::Scalar(0));
162 for(
int y = 0; y <
image.rows; ++y)
164 for(
int x = 0; x <
image.cols; ++x)
166 unsigned char v =
image.at<
unsigned char>(y, x);
177 unsigned int num_points = points.
size();
186 for(
unsigned int i = 0; i < line_starts.
size(); ++i)
188 int x2 = line_starts[i].x;
189 int y2 = line_starts[i].y;
191 while(
image.at<
unsigned char>(y2, x2) == v)
194 if (contour_map.at<
unsigned char>(y2, x2 - 1) != 0)
204 if (hole_points.
size() <= 2)
212 cv::floodFill(
image, cv::Point(x, y), 0);
224 if (vertices.
empty())
229 geo::Vec2 min(vertices[0].x, vertices[0].y);
242 double w = max.x - min.x;
243 double h = max.y - min.y;
245 cv::Mat grid(h * res + 5, w * res + 5, CV_8UC1, cv::Scalar(0));
249 for(
unsigned int i = 0; i < proj_vertices.
size(); ++i)
252 proj_vertices[i] = cv::Point2d((v.
x - min.x) * res + 1, (v.
y - min.y) * res + 1);
260 pts[0] = proj_vertices[
t.i1_];
261 pts[1] = proj_vertices[
t.i2_];
262 pts[2] = proj_vertices[
t.i3_];
263 cv::fillConvexPoly(grid, &pts[0], 3, cv::Scalar(1));
272 contours.resize(contours_pixel.
size());
273 for(
unsigned int i = 0; i < contours_pixel.
size(); ++i)
279 for(
unsigned int j = 0; j < contour.
size(); ++j)
280 contour[j] =
geo::Vec2(contour_pixel[j].x - 1, contour_pixel[j].y - 1) / res + min;