How to find number of clusters in a image?

Viewed 2655

Find the number of clusters in this image:

I'm trying to find the number of cluster in this image. I tried openCV morphologyEx and erode but can't seem to get a single pixel for each cluster. Please suggest which would be the best way to count the number of clusters in an image using openCV preferably in Python.

--Edit

I tried thinning, erode and morphologyEx(closing) but couldn't converge the clusters to a single pixel. Below are some of things I tried.

kernel = np.ones((2, 2), np.uint8) #[[1,1,1],[1,1,1],[1,1,1]
erosion = cv2.erode(img, kernel, iterations=1)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imwrite('test1.jpg', erosion)
cv2.imwrite('test2.jpg', closing)

img = cv2.imread(file, 0)
size = np.size(img)
skel = np.zeros(img.shape, np.uint8)

#ret, img = cv2.threshold(img, 127, 255, 0)
element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
done = False

while (not done):
    eroded = cv2.erode(img, element)
    temp = cv2.dilate(eroded, element)
    temp = cv2.subtract(img, temp)
    skel = cv2.bitwise_or(skel, temp)
    img = eroded.copy()

    zeros = size - cv2.countNonZero(img)
    if zeros == size:
        done = True

cv2.imwrite('thinning.jpg', skel)
2 Answers

How is this?

import numpy as np
import cv2

img = cv2.imread('points.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

n_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh)

print(n_labels)

size_thresh = 1
for i in range(1, n_labels):
    if stats[i, cv2.CC_STAT_AREA] >= size_thresh:
        #print(stats[i, cv2.CC_STAT_AREA])
        x = stats[i, cv2.CC_STAT_LEFT]
        y = stats[i, cv2.CC_STAT_TOP]
        w = stats[i, cv2.CC_STAT_WIDTH]
        h = stats[i, cv2.CC_STAT_HEIGHT]
        cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), thickness=1)

cv2.imwrite("out.jpg", img)

number of cluster : 974
out.jpg :
enter image description here

Solution is as simple as this. You should find number of contours of the image and count them. For that you can use cv2.findContours method with following parameters. For further details about cv2.findContours please check the documentation.

import cv2
img = cv2.imread('test.jpg', 0)
cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU,img)

image, contours, hier = cv2.findContours(img, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
count = len(contours)
print(count)

output:

973
Related