Search code examples
opencvcontouremgucvcanny-operatoradaptive-threshold

Find shapes on white background. Thinning the lines


I have the following image as a test image:

enter image description here

I attempt to find the shapes on the image (and other images). My approch right now is the following:

  1. Gaussian blur with a 3x3 kernel
  2. Canny edge detection using list (to get all shapes)
  3. Morphology with MorphOp.Close to close the edges
  4. FindContours to find contours
  5. Iteration of each contour:
    1. Find ApproxPolyDP
    2. Find ConvexHull
    3. Discard if hull size < 2, approx area < 200 or hull size > 50000, or arclength of the approx < 100
    4. Draw convexhull

This method yields the following images where the convex hulls are drawn: enter image description here

This is almost perfect, but notice that the lines are seen as a contours events->suppliers and events->documents). When looking at the edge information, it becomes apparent why this is so:

enter image description here

The lines are detected as a contour. How could I prepare/find the shapes so the lines are not detected? I though of some thinning algorithm, but since I also work on real life images it is difficult to find a threshold that works. Here is an example of a real life image where thinning is difficult to do because thinning typically requires the images to be monochrome in black and white.

enter image description here

How would you do it? Is there some method to determine if the contour/convex hull is a line, rectangle or something like this?


Solution

  • I ended up using a mix of overlapping test and convexity scan. The convexity scans for the error between the convex hull and the actual contour. If this error exceeds a certain amount, the hull is ignored. The overlapping simply use bitwise and to detech if two convex hull's overlap. If they overlap more than 95% percent, one of them is ignored.