【OpenCV】基于kmeans的细胞检测方法
问题是这样的,有一幅经过二值化处理之后的图像,我们希望统计其中细胞的个数,和不同粘连情况的细胞个数,比如,下图中有1个细胞组成连通区域的,也有2个细胞组成连通区域的,也有更多个细胞组成连通区域的,我们希望分别统计不同的情况。
我想出的一种可行的方法是这样的:
- 通过图像形态学的处理erode,将一些邻接的细胞分离开来,并减少单个像素的噪声干扰
- 计算其中的连通域
- 计算每一个连通域的面积
- 根据面积计算其中的聚类,其中聚类算法采用kmeans,其中k,由用户设定
- 根据聚类的情况计算其中细胞数
里面的采用聚类的思想是根据不同类型的重叠细胞,其中的面积应该有相应的分布,比如,两个重叠的细胞面积往往会显著的小于三个重叠的细胞(但是肯定会有例外),我们基于以上的想法通过计算聚类的方法计算其中的细胞数。
import cv2 from numpy import * from scipy.cluster.vq import * img=cv2.imread('FigProb9.27.jpg',0) kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3)) img=cv2.erode(img,kernel,iterations=5) contour,h=cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) cv2.drawContours(img,contour,-1,(255,0,0),1) cv2.imshow('img',img) ContourArea=[] for cnt in contour: Area=cv2.contourArea(cnt) ContourArea.append(Area) ContourArea=array(ContourArea) ContourArea=ContourArea[ContourArea>20] #print len(ContourArea) # print ContourArea # print min(ContourArea) # print max(ContourArea) # print average(ContourArea) #print sort(ContourArea) centroid,dis=kmeans(ContourArea,5)#calculate 5 cluster label,dis=vq(ContourArea,sort(centroid))#calculate label in 5 cluster clusterNum=[]#the amount cluster classNum=[]#the total amount cell in this kind of cluster for i in range(len(label)): clusterNum.append(len(label[label==i])) classNum.append(clusterNum[i]*(i+1)) print ("In picture,we can see Total amount of cell is %d.\n ")%(sum(classNum)) print("%d in one;%d in two;%d in three;%d in four;%d in five.")%(classNum[0],classNum[1],classNum[2],classNum[3],classNum[4]) cv2.waitKey()