opencv——python细胞计数实现

opencv——python细胞计数实现

写程序萌新(不准备干程序员),上周看公司同事在学python,因为公司最近没什么事做(实际因为公司业务萎缩裁员降薪正融资)作为产品我也很无奈,公司程序基本裁完了,想着反正闲着也是闲着,就在周末找个python视频看看,就看了个基础教程,想着用opencv实现个细胞计数功能,周末看了看python基础语法,这两天看了看opencv基本操作,总共入门5天时间,就想试试看,非常膨胀,看了几篇文章就开干,得感谢赶上好时候,百度解决一切。
](https://img-blog.csdnimg.cn/20200108145808646.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21pY3Jvc3BvcmU=,size_16,color_FFFFFF,t_70)
首先,先对图片进行处理,步骤就是: 原图——灰度图——腐蚀膨胀——二值化阈值——滤波操作。

import cv2
import numpy as  np
img=cv2.imread(r'D:\imge\cell.jpg',1) #读取图片
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #将图片变为灰度图片
kernel=np.ones((2,2),np.uint8) #进行腐蚀膨胀操作
erosion=cv2.erode(gray,kernel,iterations=5) 
dilation=cv2.dilate(erosion,kernel,iterations=5) 
ret, thresh = cv2.threshold(dilation, 150, 255, cv2.THRESH_BINARY) # 阈值处理 二值化 用150不用255是因为有些细胞就直接变白
thresh1 = cv2.GaussianBlur(thresh,(3,3),0)# 高斯滤波

在这里插入图片描述
然后,找出连通域对连通域进行操作。因为处理后图仍有细小的杂文无法去除,通过观察细胞大小确定面积,将小值过滤。

#对连通域面积进行比较
area=[] #建立空数组,放连通域面积
contours1=[]   #建立空数组,放减去后的数组
for i in contours:
      # area.append(cv2.contourArea(i))
      # print(area)
     if cv2.contourArea(i)>30:  # 计算面积 去除面积小的 连通域
        contours1.append(i)
print(len(contours1)-1) #计算连通域个数
draw=cv2.drawContours(img,contours1,-1,(0,255,0),1) #描绘连通域

其次,因为数数的问题,每个细胞要显示数字。做法就是求每个连通域的重心,将数字绘制在重心上即可。

#求连通域重心 以及 在重心坐标点描绘数字
for i,j in zip(contours1,range(len(contours1))):
    M = cv2.moments(i)
    cX=int(M["m10"]/M["m00"])
    cY=int(M["m01"]/M["m00"])
    draw1=cv2.putText(draw, str(j), (cX, cY), 1,1, (255, 0, 255), 1) #在中心坐标点上描绘数字

最后展示图即可
在这里插入图片描述

cv2.imshow("draw",draw1)
cv2.imshow("thresh1",thresh1)
cv2.waitKey()
cv2.destroyWindow()

最后源代码

import cv2
import numpy as  np
img=cv2.imread(r'D:\imge\cell.jpg',1) #读取图片
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #将图片变为灰度图片
kernel=np.ones((2,2),np.uint8) #进行腐蚀膨胀操作
erosion=cv2.erode(gray,kernel,iterations=5) #膨胀
dilation=cv2.dilate(erosion,kernel,iterations=5) #腐蚀
ret, thresh = cv2.threshold(dilation, 150, 255, cv2.THRESH_BINARY) # 阈值处理 二值法
thresh1 = cv2.GaussianBlur(thresh,(3,3),0)# 高斯滤波
contours,hirearchy=cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 找出连通域
#对连通域面积进行比较
area=[] #建立空数组,放连通域面积
contours1=[]   #建立空数组,放减去最小面积的数
for i in contours:
      # area.append(cv2.contourArea(i))
      # print(area)
     if cv2.contourArea(i)>30:  # 计算面积 去除面积小的 连通域
        contours1.append(i)
print(len(contours1)-1) #计算连通域个数
draw=cv2.drawContours(img,contours1,-1,(0,255,0),1) #描绘连通域
#求连通域重心 以及 在重心坐标点描绘数字
for i,j in zip(contours1,range(len(contours1))):
    M = cv2.moments(i)
    cX=int(M["m10"]/M["m00"])
    cY=int(M["m01"]/M["m00"])
    draw1=cv2.putText(draw, str(j), (cX, cY), 1,1, (255, 0, 255), 1) #在中心坐标点上描绘数字
#展示图片
cv2.imshow("draw",draw1)
cv2.imshow("thresh1",thresh1)
cv2.waitKey()
cv2.destroyWindow()

有不完美的地方,最大的连通域不知道怎么形成的,如果知道可以告诉下,让我修改下程序,thanks。

  • 36
    点赞
  • 228
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值