分水岭分割后的细胞计数 -- openCV/Python
counting cells after watershed segmentation -- openCV/Python
我关注了this tutorial given on watershed segmentation to separate the brown cells on the attached image. It went well (cells are separated by blue boundary) but now I would like to count those cells and determine their sizes(pixel number) in order to plot a distribution function. Could you please help how to do it?
代码如下。
import numpy as np
import cv2
img = cv2.imread('test watershed.tif')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# noise removal
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=3)
# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform,0.1*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
markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]
**UPDATE**
#thresholding a color image, here keeping only the blue in the image
th=cv2.inRange(img,(255,0,0),(255,0,0)).astype(np.uint8)
#inverting the image so components become 255 seperated by 0 borders.
th=cv2.bitwise_not(th)
#calling connectedComponentswithStats to get the size of each component
nb_comp,output,sizes,centroids=cv2.connectedComponentsWithStats(th,connectivity=4)
#taking away the background
nb_comp-=1; sizes=sizes[0:,-1]; centroids=centroids[1:,:]
bins = list(range(np.amax(sizes)))
#plot distribution of your cell sizes.
numbers = sorted(sizes)
plt.hist(sizes,numbers)
cv2.imwrite("test watershed result",img)
您完成了最困难的部分!现在只需对结果进行阈值(按颜色)并调用方便的 connectedComponentsWithStats
#thresholding a color image, here keeping only the blue in the image
th=cv2.inRange(img,(255,0,0),(255,0,0)).astype(np.uint8)
#inverting the image so components become 255 seperated by 0 borders.
th=cv2.bitwise_not(th)
#calling connectedComponentswithStats to get the size of each component
nb_comp,output,sizes,centroids=cv2.connectedComponentsWithStats(th,connectivity=4)
#taking away the background
nb_comp-=1; sizes=sizes[1:,-1]; centroids=centroids[1:,:]
#plot distribution of your cell sizes (using matplotlib.pyplot as plt)
plt.hist(sizes)
我关注了this tutorial given on watershed segmentation to separate the brown cells on the attached image. It went well (cells are separated by blue boundary) but now I would like to count those cells and determine their sizes(pixel number) in order to plot a distribution function. Could you please help how to do it?
代码如下。
import numpy as np
import cv2
img = cv2.imread('test watershed.tif')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
# noise removal
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=3)
# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform,0.1*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
markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]
**UPDATE**
#thresholding a color image, here keeping only the blue in the image
th=cv2.inRange(img,(255,0,0),(255,0,0)).astype(np.uint8)
#inverting the image so components become 255 seperated by 0 borders.
th=cv2.bitwise_not(th)
#calling connectedComponentswithStats to get the size of each component
nb_comp,output,sizes,centroids=cv2.connectedComponentsWithStats(th,connectivity=4)
#taking away the background
nb_comp-=1; sizes=sizes[0:,-1]; centroids=centroids[1:,:]
bins = list(range(np.amax(sizes)))
#plot distribution of your cell sizes.
numbers = sorted(sizes)
plt.hist(sizes,numbers)
cv2.imwrite("test watershed result",img)
您完成了最困难的部分!现在只需对结果进行阈值(按颜色)并调用方便的 connectedComponentsWithStats
#thresholding a color image, here keeping only the blue in the image
th=cv2.inRange(img,(255,0,0),(255,0,0)).astype(np.uint8)
#inverting the image so components become 255 seperated by 0 borders.
th=cv2.bitwise_not(th)
#calling connectedComponentswithStats to get the size of each component
nb_comp,output,sizes,centroids=cv2.connectedComponentsWithStats(th,connectivity=4)
#taking away the background
nb_comp-=1; sizes=sizes[1:,-1]; centroids=centroids[1:,:]
#plot distribution of your cell sizes (using matplotlib.pyplot as plt)
plt.hist(sizes)