71 #include <visp3/imgproc/vpImgproc.h>
81 if (std::fabs(from.
get_i() - to.
get_i()) < std::numeric_limits<double>::epsilon()) {
83 direction.m_direction = EAST;
86 direction.m_direction = WEST;
90 if (std::fabs(from.
get_j() - to.
get_j()) < std::numeric_limits<double>::epsilon()) {
91 direction.m_direction = SOUTH;
94 direction.m_direction = SOUTH_EAST;
97 direction.m_direction = SOUTH_WEST;
101 if (std::fabs(from.
get_j() - to.
get_j()) < std::numeric_limits<double>::epsilon()) {
102 direction.m_direction = NORTH;
105 direction.m_direction = NORTH_EAST;
108 direction.m_direction = NORTH_WEST;
117 vpDirection direction;
122 bool b = checked[(int)direction.m_direction];
128 unsigned int i = (
unsigned int)point.
get_i();
129 unsigned int j = (
unsigned int)point.
get_j();
131 return I[i][j] != 0 && ((
unsigned int)point.
get_j() == I.
getWidth() - 1 || b);
138 unsigned int i = (
unsigned int)point.
get_i();
139 unsigned int j = (
unsigned int)point.
get_j();
141 if (crossesEastBorder(I, checked, point)) {
144 else if (I[i][j] == 1) {
153 if (!fromTo(ij, i2j2, dir)) {
157 vpDirection trace = dir.clockwise();
161 while (trace.m_direction != dir.m_direction) {
164 if (activePixel.
get_i() >= 0 && activePixel.
get_j() >= 0) {
169 trace = trace.clockwise();
172 if (i1j1.get_i() < 0 || i1j1.get_j() < 0) {
180 bool checked[8] = {
false,
false,
false,
false,
false,
false,
false,
false };
183 if (!fromTo(i3j3, i2j2, dir)) {
187 trace = dir.counterClockwise();
191 for (
int cpt = 0; cpt < 8; cpt++) {
192 checked[cpt] =
false;
196 i4j4 = trace.active(I, i3j3);
197 if (i4j4.get_i() >= 0 && i4j4.get_j() >= 0) {
201 checked[(int)trace.m_direction] =
true;
202 trace = trace.counterClockwise();
205 addContourPoint(I, border, i3j3, checked, nbd);
207 if (i4j4 == ij && i3j3 == i1j1) {
218 bool isOuterBorderStart(
const vpImage<int> &I,
unsigned int i,
unsigned int j)
220 return (I[i][j] == 1 && (j == 0 || I[i][j - 1] == 0));
223 bool isHoleBorderStart(
const vpImage<int> &I,
unsigned int i,
unsigned int j)
225 return (I[i][j] >= 1 && (j == I.
getWidth() - 1 || I[i][j + 1] == 0));
235 contour_list.
m_children.push_back(contour_node);
238 for (std::vector<vp::vpContour *>::const_iterator it = root.
m_children.begin(); it != root.
m_children.end(); ++it) {
239 getContoursList(**it, level + 1, contour_list);
252 for (std::vector<std::vector<vpImagePoint> >::const_iterator it1 = contours.begin(); it1 != contours.end(); ++it1) {
253 for (std::vector<vpImagePoint>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
254 unsigned int i = (
unsigned int)it2->get_i();
255 unsigned int j = (
unsigned int)it2->get_j();
267 for (std::vector<std::vector<vpImagePoint> >::const_iterator it1 = contours.begin(); it1 != contours.end(); ++it1) {
268 for (std::vector<vpImagePoint>::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) {
269 unsigned int i = (
unsigned int)it2->get_i();
270 unsigned int j = (
unsigned int)it2->get_j();
271 I[i][j] =
vpRGBa(color.
R, color.
G, color.
B);
279 if (I_original.
getSize() == 0) {
288 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
294 for (
unsigned int j = 0; j < I_original.
getWidth(); j++) {
295 I[i][j + 1] = I_original[i - 1][j];
311 std::map<int, vpContour *> borderMap;
312 borderMap[lnbd] = root;
314 for (
unsigned int i = 0; i < I.
getHeight(); i++) {
317 for (
unsigned int j = 0; j < I.
getWidth(); j++) {
320 bool isOuter = isOuterBorderStart(I, i, j);
321 bool isHole = isHoleBorderStart(I, i, j);
323 if (isOuter || isHole) {
333 borderPrime = borderMap[lnbd];
357 borderPrime = borderMap[lnbd];
377 followBorder(I, ij, from, border, nbd);
387 contourPts.push_back(border->
m_points);
390 borderMap[nbd] = border;
394 if (fji != 0 && fji != 1) {
395 lnbd = std::abs(fji);
404 for (std::vector<vpContour *>::iterator it = contours.
m_children.begin(); it != contours.
m_children.end(); ++it) {
406 if (*it !=
nullptr) {
417 for (std::vector<vpContour *>::const_iterator it = root->
m_children.begin(); it != root->
m_children.end(); ++it) {
419 std::vector<vpContour *> children_copy = (*it)->m_children;
421 (*it)->m_children.clear();
425 (*it)->m_children = children_copy;
427 for (
size_t i = 0; i < contours.
m_children.size(); i++) {
430 contourPts.push_back((*it)->m_points);
434 getContoursList(*root, 0, contours);
437 for (std::vector<vpContour *>::iterator it = contours.
m_children.begin(); it != contours.
m_children.end(); ++it) {
438 (*it)->m_parent = &contours;
Class to define RGB colors available for display functionalities.
error that can be emitted by ViSP classes.
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition of the vpImage class member functions.
unsigned int getWidth() const
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
VISP_EXPORT void findContours(const vpImage< unsigned char > &I_original, vpContour &contours, std::vector< std::vector< vpImagePoint > > &contourPts, const vpContourRetrievalType &retrievalMode=vp::CONTOUR_RETR_TREE)
VISP_EXPORT void drawContours(vpImage< unsigned char > &I, const std::vector< std::vector< vpImagePoint > > &contours, unsigned char grayValue=255)
vpContourType m_contourType
Contour type.
void setParent(vpContour *parent)
vpContour * m_parent
Parent contour.
std::vector< vpImagePoint > m_points
Vector of points belonging to the contour.
std::vector< vpContour * > m_children
Children contour.