I'm trying to count the number of pieces a glass broke into, using OpenCV (cv2 / Python).
One input example is this image:
Following the tutorial I found here, I identified a sure foreground and background and then used the Watershed algorithm.
I got this result:
As you can see, the solution is not perfect: Some pieces are split into two, some are merged with others. Also the long lines that should be ignored are seen as borders sometimes.
Do you have different ideas for techniques I could use? I'm pretty new to OpenCV.
Thanks! :)
EDIT: Here's my code because commenters asked for it. As I said, it follows the posted link.
import cv2
import matplotlib.pyplot as plt
import numpy as np
import sys
%matplotlib inline
# Default show images in greyscale
plt.gray()
img = cv2.imread('../data/raw/example.jpg',0)
# noise removal
img = cv2.GaussianBlur(img, (5, 5), 0)
ret, thresh = cv2.threshold(img,0,255,cv2.THRESH_OTSU)
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
# sure background area
sure_bg = cv2.dilate(opening,kernel,iterations=1)
# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform,0.4*dist_transform.max(),255,0)
# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)
# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg)
# Add one to all labels so that sure background is not 0, but 1
markers = markers+1
# Now, mark the region of unknown with zero
markers[unknown==255] = 0
# Watershed
img_color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
markers = cv2.watershed(img_color,markers)
img_color[markers == -1] = [255,0,0]
def plot_image(image, figsize=(18,18)):
fig, ax = plt.subplots(figsize=(18, 20))
ax.imshow(image, cmap='gray')
plt.show()
plot_image(img_color)