How to count overlapping contours

Viewed 172

I have those contours which are overlapping.

Contours example

Right now I can count 3 different contours, but I need to count all of the overlapping ones, so in total 9. How can I separate all contours from each other, to count the right amount? I use GaussianBlur, and Canny for the segmentation and cv2.dilate to strengthen the contours.

Here is the detectation of the contours, image is the loaded image as GRAYSCALE, segment is the segmented image mentioned above:

(sticks, hierarchy) = cv2.findContours(segment.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnt = len(sticks)

rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB )
cv2.drawContours(rgb, sticks, -1, (255, 0, 0), 1)
print(f'Counted bad: {cnt}')

cv2.imshow('img', rgb)
1 Answers

This solution is not generic but will work for the input image you have provided. You can use vertical and horizontal kernels and erode the image to consequently remove the horizontal or vertical contours. After removing, then as you are doing currently, find the contours and count them.

import cv2
import numpy as np

img = cv2.imread('overlap.jpg', 0)

kernel_h = np.ones((1, 39), dtype=np.uint8)
kernel_v = np.ones((39, 1), dtype=np.uint8)
horizontal = cv2.erode(img, kernel_h)
vertical = cv2.erode(img, kernel_v)

sticks_h, _ = cv2.findContours(horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
sticks_v, _ = cv2.findContours(vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
print('Total count is:', len(sticks_h) + len(sticks_v))

cv2.imshow('original', img)
cv2.imshow('horizontal', horizontal)
cv2.imshow('vertical', vertical)
cv2.waitKey(0)
cv2.destroyAllWindows()

The horizontal contours. horizontal contours

The vertical contours. vertical contours

This solution would fail for images having two or more intersecting horizontal or vertical contours. It would also fail if the shape of the contours doesn't have a big height to width ratio or visa-versa.

Related