I need to return the number of grains present in the image. There are a lot of grains present and all of them are overlapping. can someone help me out with this problem? thanks in advance.
The objective here is to create some segmentation algorithms using OpenCV and Python to segment each grain and count the number of grains in the image.


This is not a complete algorithm; and definitely has an error and probably not for all test cases. But it can be a good place to start. You have to take time; Explore different ideas; Check out different test cases; Learn and explore image processing techniques to achieve better outputs.
import sys
import cv2
import numpy as np
# Load image
im = cv2.imread(sys.path[0]+'/im.png', cv2.IMREAD_GRAYSCALE)
H, W = im.shape[:2]
# Remove noise
im = cv2.medianBlur(im, 9)
im = cv2.GaussianBlur(im, (11, 11), 21)
# Find outlines
im = cv2.adaptiveThreshold(
im, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 61, 2)
top1 = im.copy()
# Fill area with black to find seeds
cv2.floodFill(im, np.zeros((H+2, W+2), np.uint8), (0, 0), 0)
im = cv2.erode(im, np.ones((5, 5)))
top2 = im.copy()
# Find seeds
cnts, _ = cv2.findContours(im, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
# Convert GRAY instances to BGR
top1 = cv2.cvtColor(top1, cv2.COLOR_GRAY2BGR)
top2 = cv2.cvtColor(top2, cv2.COLOR_GRAY2BGR)
im = cv2.cvtColor(im, cv2.COLOR_GRAY2BGR)
# Draw circle around detected seeds
c = 0
for cnt in cnts:
x, y, w, h = cv2.boundingRect(cnt)
cv2.circle(im, (x+w//2, y+h//2), max(w, h)//2, (c, 150, 255-c), 3)
c += 5
im=~im
# Print number of seeds
print(len(cnts))
# Save output
cv2.imwrite(sys.path[0]+'/out.png', np.hstack((top1,top2,im)))

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With