基于OpenCV的血球计数板图像酵母细胞计数及死细胞识别需求
酵母细胞计数与死细胞筛选的OpenCV解决方案
一、预处理修正与细胞掩码优化
你当前代码里存在冗余操作:先转灰度再转RGB是错误且无意义的(灰度图为单通道,无法直接转换为RGB)。以下是修正后的预处理流程,能得到更干净的细胞掩码:
import cv2 import numpy as np import matplotlib.pyplot as plt # 读取图像并转为RGB(OpenCV默认读取为BGR格式) im = cv2.imread('Yeast.jpg') im_rgb = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) # 灰度化+去噪 gray = cv2.cvtColor(im_rgb, cv2.COLOR_RGB2GRAY) blur = cv2.medianBlur(gray, 3) # 自适应阈值二值化(适配光照不均场景) thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 形态学开运算去除小噪点 kernel = np.ones((3,3), np.uint8) clean_thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=1) plt.imshow(clean_thresh, cmap='gray')
二、提取单个细胞斑点(解决重叠细胞分割)
直接用轮廓检测会把重叠细胞识别为一个整体,这里用距离变换+分水岭算法分割重叠区域:
# 距离变换:计算前景像素到背景的距离,突出细胞中心 dist_transform = cv2.distanceTransform(clean_thresh, cv2.DIST_L2, 5) # 阈值筛选得到细胞中心种子点 ret, sure_fg = cv2.threshold(dist_transform, 0.2*dist_transform.max(), 255, 0) sure_fg = np.uint8(sure_fg) # 确定背景区域与未知重叠区域 sure_bg = cv2.dilate(clean_thresh, kernel, iterations=3) unknown = cv2.subtract(sure_bg, sure_fg) # 标记连通区域,为分水岭算法做准备 ret, markers = cv2.connectedComponents(sure_fg) markers = markers + 1 # 背景标记设为1,避免与未知区域混淆 markers[unknown==255] = 0 # 应用分水岭分割细胞 markers = cv2.watershed(im_rgb, markers) im_rgb[markers == -1] = [255,0,0] # 用红色标记细胞分割边界 # 统计总细胞数(标记值从2开始,减去背景和边界标记) cell_count_total = len(np.unique(markers)) - 2 print(f"总细胞数:{cell_count_total}")
三、筛选不接触其他细胞的细胞
通过膨胀细胞掩码并检查重叠,判断细胞是否独立:
# 提取每个细胞的单独掩码 cell_masks = [] for label in range(2, markers.max()+1): mask = np.zeros_like(gray) mask[markers == label] = 255 cell_masks.append(mask) # 筛选无接触的独立细胞 independent_cells = [] for i, mask in enumerate(cell_masks): # 膨胀当前细胞掩码,模拟接触范围 dilated = cv2.dilate(mask, kernel, iterations=2) # 检查是否与其他细胞掩码重叠 overlap = False for j, other_mask in enumerate(cell_masks): if i != j and cv2.bitwise_and(dilated, other_mask).any(): overlap = True break if not overlap: independent_cells.append(mask) print(f"独立细胞数:{len(independent_cells)}")
四、识别并计数蓝色死细胞
在HSV颜色空间中筛选蓝色区域,稳定性优于RGB:
# 转换为HSV空间 hsv = cv2.cvtColor(im_rgb, cv2.COLOR_RGB2HSV) # 蓝色的HSV范围(可根据实际图像微调) lower_blue = np.array([90, 50, 50]) upper_blue = np.array([130, 255, 255]) blue_mask = cv2.inRange(hsv, lower_blue, upper_blue) # 统计独立细胞中的蓝色死细胞 dead_cell_count = 0 for mask in independent_cells: # 提取细胞区域内的蓝色部分 cell_blue = cv2.bitwise_and(blue_mask, mask) # 判断蓝色区域占比是否超过阈值(比如50%) blue_area = cv2.countNonZero(cell_blue) cell_area = cv2.countNonZero(mask) if cell_area > 0 and blue_area / cell_area > 0.5: dead_cell_count += 1 print(f"符合条件的死细胞数:{dead_cell_count}")
五、是否需要训练目标检测模型?
如果你的图像存在大量不规则重叠、极端光照变化,或需要适配多种复杂场景,训练YOLO、Faster R-CNN等模型是可行方案;但对于常规酵母计数任务,上述传统CV方法足够简便,无需标注大量数据,仅需微调参数即可适配多数场景。
内容的提问来源于stack exchange,提问作者Stefan Wiswedel
相关产品推荐
相关产品推荐

