Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Increasing segmentation depth using Watershed

Hi all,

I'm trying to segment images containing a lot of individual objects. I'm applying the watershed algorithm to get the effect I want.

image description.

As you can see, the watershed algorithm is very good at picking out single objects. However, you can also see clumps of the same object in the picture. I want to extract each image as well as possible.

Can I get some guidance as to the best tactic? My code for performing the segmentation is below. I apply a few morphologies to open and close the fg/bg and apply a threshold to the image. I proceed by picking out the white parts of the threshold and using them and obtaining lables from them:

   kernel = np.ones((3,3),np.uint8)
  gray = cv2.GaussianBlur(image, (15, 15), 0)
#shifted = cv2.pyrMeanShiftFiltering(shifted, 20, 45, 3);
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
if invert:
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 115, 1)
else:
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)

#_, thresh = cv2.threshold(shifted, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) closing = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel, iterations = 2) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

# sure background area

sure_fg = cv2.erode(closing,kernel,iterations=2)
sure_bg = cv2.dilate(opening,kernel,iterations=2)

# Finding sure foreground area
dt = cv2.distanceTransform(sure_bg,cv2.DIST_L2,5)
dt = ((dt - dt.min()) / (dt.max() - dt.min()) * 255).astype(np.uint8)
dt = cv2.normalize(dt, None, 255,0, cv2.NORM_MINMAX, cv2.CV_8UC1)
ret, sure_fg = cv2.threshold(dt,int(float(md_lim)/(100.0)*dt.max()),255,0)

#ret,sure_bg = cv2.threshold(sure_bg,1,128,1)

Finding unknown region

sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)

# Marker labelling
ret, labels = cv2.connectedComponents(sure_fg)

# Add one to all labels so that sure background is not 0, but 1
labels = labels+1

N ow, mark the region of unknown with zero

labels[unknown==255] = 0

labels = cv2.watershed(image,labels)
image[labels == -1] = [255,0,0]

Increasing segmentation depth using Watershed

Hi all,

I'm trying to segment images containing a lot of individual objects. I'm applying the watershed algorithm to get the effect I want.

image description.

As you can see, the watershed algorithm is very good at picking out single objects. However, you can also see clumps of the same object in the picture. I want to extract each image as well as possible.

Can I get some guidance as to the best tactic? My code for performing the segmentation is below. I apply a few morphologies to open and close the fg/bg and apply a threshold to the image. I proceed by picking out the white parts of the threshold and using them and obtaining lables from them:

   kernel = np.ones((3,3),np.uint8)
  gray = cv2.GaussianBlur(image, (15, 15), 0)
#shifted = cv2.pyrMeanShiftFiltering(shifted, 20, 45, 3);
gray = cv2.cvtColor(gray, cv2.COLOR_BGR2GRAY)
if invert:
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 115, 1)
else:
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)

#_, thresh = cv2.threshold(shifted, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) closing = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel, iterations = 2) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

# sure background area
2)


sure_fg = cv2.erode(closing,kernel,iterations=2)
sure_bg = cv2.dilate(opening,kernel,iterations=2)

# Finding sure foreground area
dt = cv2.distanceTransform(sure_bg,cv2.DIST_L2,5)
dt = ((dt - dt.min()) / (dt.max() - dt.min()) * 255).astype(np.uint8)
dt = cv2.normalize(dt, None, 255,0, cv2.NORM_MINMAX, cv2.CV_8UC1)
ret, sure_fg = cv2.threshold(dt,int(float(md_lim)/(100.0)*dt.max()),255,0)

#ret,sure_bg = cv2.threshold(sure_bg,1,128,1)

Finding unknown region

sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)

# Marker labelling
ret, labels = cv2.connectedComponents(sure_fg)

# Add one to all labels so that sure background is not 0, but 1
labels = labels+1

N ow, mark the region of unknown with zero

 labels[unknown==255] = 0

labels = cv2.watershed(image,labels)
image[labels == -1] = [255,0,0]