0

On a discrete grid-based plane (think: pixels of an image), I have a closed contour that can be expressed either by:

  • a set of 2D points (x1,y1);(x2,y2);(x3,y3);...
  • or a 4-connected Freeman code, with a starting point: (x1,y1) + 00001112...

I know how to switch from one to the other of these representations. This will be the input data.

I want to get the set of grid coordinates that are bounded by the contour. Consider this example, where the red coordinates are the contour, and the gray one the starting point:

Sample contour

If the gray coordinate is, say, at (0,0), then I want a vector holding: (1,1),(2,1),(3,1),(3,2)

Order is not important, and the output vector can also hold the contour itself.

Language of choice is C++, but I'm open to any existing code, algorithm, library, pointer, whatever...

I though that maybe CGAL would have something like this, but I am unfamiliar with it and couldn't find my way through the manual, so I'm not even sure. I also looked toward Opencv but I think it does not provide this algorithm (but I can be wrong?).

I was thinking about finding the bounding rectangle, then checking each of the points in the rectangle to see if they are inside/outside, but this seems suboptimal. Any idea ?

kebs
  • 6,387
  • 4
  • 41
  • 70
  • 3
    All you need to do is find a single point inside the boundary, and then flood fill. This is a simple recursive algorithm. – j_random_hacker Jun 17 '14 at 01:03
  • 1
    You should check if "finding the bounding rectangle" is really a slow one. If your contour is not very large, it is probably fastest to draw the countour into a 2D array and then flood fill as j_random_hacker suggests. Otherwise you'll have hard time finding out which grid position belongs to the contour. – DrV Jun 17 '14 at 08:14
  • @j_random_hacker Thanks, I didn't think of that one indeed, but it seems a good idea. Maybe not a recursive implementation, though, as I'm afraid it might not be the fastest. I'll investigate. – kebs Jun 17 '14 at 08:33
  • @DrV The problem with the bounding rectangle is that if the shape is deeply concave (think about the external shape of the letter "U" for example), then it could take some time to find a point that is inside the contour. – kebs Jun 17 '14 at 08:36
  • @DrV Forget the above comment, I can indeed easily find an "inside" point just by taking one that is "just next" to a contour point... – kebs Jun 17 '14 at 08:39
  • 1
    Actually, finding the "inside" is not that simple, as both the "outside" and the "inside" are next to the contour points. By using the Freeman code, you can calculate the number of turns left and turns right you take during the cycle. If you do more left turns, your countour runs counterclockwise, and "inside" is on your left if you go along the countour. – DrV Jun 17 '14 at 09:13
  • If you don't want to use a recursive implementation, feel free to use a BFS, for instance. – user189 Jun 17 '14 at 09:34
  • @DrV That problem is already solved, as my chain-code is normalized, i.e. its starting point (x0,y0) is always the lowest coordinate (x_min first, then y_min), and the orientation is set to counter-clockwise. So the first chain-code value is always "0" (regular 4-connected Freeman code). And this way, I **know** that the point (x0+1,y0+1) is inside. – kebs Jun 17 '14 at 09:38

1 Answers1

1

One way to solve this is drawContours, and you have contours points with you.

  1. Create blank Mat and draw contour with thickness = 1(boundary).
  2. Create another blank Mat and draw contour with thickness = CV_FILLED(whole area including boundary).
  3. Now bitwise_and between above two(you got filled area excluding boundary).
  4. Finally check for non-zero pixel.
Haris
  • 13,645
  • 12
  • 90
  • 121
  • Thanks for answering. The problem with this approach is point 4: this means parsing all the pixels 1 by 1. If I have a large grid and contours that have only a small area, it is sub-optimal. But the biggest problem is that I have **several** contours, and with this method I cannot know what pixels belong to what contour. – kebs Jun 18 '14 at 06:56