1

I'm in the process of writing a C program using OpenCV to detect some rectangles made with tape, which are hollow on the inside. Problem is, each physical rectangle gives two digital rectangles: one for the inner perimeter, one for the outer perimeter. The outer rectangle in all cases completely encloses the inner rectangle.

I need some way to remove the inner rectangles, and in a reasonably efficient manner, as this is being run on a video feed and must not drop framerate considerably (approx. 15fps, on a BeagleBoard xM, which is not terribly powerful).

There are always four physical rectangles, and somewhere between four to eight digital rectangles depending on the cleanliness of the processing operations. The outer rectangle is detected reliably; the inner rectangle is not. The image is thresholded, eroded, and dilated such that the image is clean and detection is reliable in general.

I feel that this problem is separate from OpenCV and is really just working with rectangles and could probably be solved by me with some time, but the project is on a crunch deadline, so I'm also throwing this question in. Thanks in advance, guys.

Backgammon
  • 454
  • 5
  • 15

3 Answers3

2

there is a function called grouprectangle in opencv.

The function can remove multiple rectangles...

Have a happy coding.

G453
  • 1,446
  • 10
  • 13
  • Yes, it is in the C++ version of OpenCV. No, it is not in the C version. This is a C program. There is no direct analog in the C version; there are the Haar classifier cascades, which aren't quite the same and aren't used in the same way. – Backgammon Feb 15 '12 at 03:34
  • Also groupRectangle doesn't return non-grouped rectangles: http://stackoverflow.com/questions/21421070/opencv-grouprectangles-getting-grouped-and-ungrouped-rectangles – Ben Dowling Jan 29 '14 at 02:47
1

Since you only have at most 8 digital rectangles, I think it would be fine to use the natural, brute force, algorithm to figure out which rectangles are inside other rectanges. It's OK to do O(N^2) algorithms when N is small, and 8 is small.

Here is the pseudo code:

for each rectangle i {
  for each rectangle j {
    if i != j and rectangle i is inside rectangle j {
      disregard rectangle i
    }
  }
}
David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • 1
    It's the `i is inside rectangle j` part that I had trouble thinking of; I had to sleep on it, and I'm surprised I didn't realize that there was a simple solution earlier. – Backgammon Feb 15 '12 at 03:42
1

Solved - the speedy solution is to take the distance to one of the corners from the center point of the rectangle, and compare that distance between rectangles whose centers are very close together. The one with the shorter distance must be the inner rectangle.

Code-wise you'd want to calculate the center, then find, say, the bottom right point, which is just the point with both min x and min y. Calculate the distance between them and store it somehow. For each rectangle, iterate over the other ones and check if their centers are very close (a constant of ~30px works fine for this in my case). Compare the distances calculated earlier; the rectangle with the shorter distance should be deleted from the list of rectangles.

Backgammon
  • 454
  • 5
  • 15