You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCV的白细胞(WBC)轮廓检测与计数实现方案咨询

白细胞(WBCs)轮廓检测与计数实现

完成二值化闭运算操作后,按「轮廓提取→有效轮廓筛选→计数可视化」三步即可完成目标,具体实现如下:


现有预处理代码的问题修正

你当前代码中HSV空间转灰度的参数错误,cv2.COLOR_BGR2GRAY仅适用于BGR三通道图转灰度,HSV图直接调用该参数会得到色彩失真的灰度结果,修正后预处理逻辑稳定性会明显提升。

核心实现步骤

1. 轮廓检测

对闭运算得到的二值图调用轮廓检测接口,选择仅检测外轮廓模式,避免把细胞内部的暗区/孔洞识别为独立细胞:

# 检测轮廓,兼容OpenCV3/4版本返回值格式
contours, hierarchy = cv2.findContours(closing.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

2. 有效轮廓过滤

预处理后残留的噪点、图像边缘的杂质团块会被识别为轮廓,需要通过面积阈值过滤无效目标:

  • 面积过小:滤波残留的噪点,直接丢弃
  • 面积过大:多个细胞粘连的团块、背景大块杂质,可根据需求选择标记或做二次分割
valid_wbc = []
# 面积阈值需根据你的图像分辨率、拍摄倍率调整,以下为参考值
min_area = 200
max_area = 3000
for cnt in contours:
    area = cv2.contourArea(cnt)
    if min_area < area < max_area:
        valid_wbc.append(cnt)

如果你处理的样本存在大量细胞粘连的情况,可在轮廓检测前增加距离变换+分水岭分割步骤,拆分粘连细胞后再计数,准确率会更高。

3. 结果可视化与计数

遍历所有有效轮廓,在原图上绘制标记、统计总数:

wbc_count = len(valid_wbc)
for i, cnt in enumerate(valid_wbc, 1):
    # 绘制细胞轮廓
    cv2.drawContours(output, [cnt], -1, (0,255,0), 2)
    # 标记细胞序号
    M = cv2.moments(cnt)
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])
    cv2.putText(output, str(i), (cX-10, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 2)

# 在图上标注总计数
cv2.putText(output, f"WBC Count: {wbc_count}", (20,40), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255,0,0), 3)
# 保存结果
cv2.imwrite("wbc_count_result.jpg", output)
print(f"检测到白细胞总数:{wbc_count}")

完整可运行代码

把修正后的预处理和后续逻辑整合后代码如下:

import cv2
import numpy as np

# 读取图像
im = cv2.imread("images/image.jpg")
output = im.copy()

# 修正:正确的灰度转换逻辑
gray_image = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
blurM = cv2.medianBlur(gray_image, 5)
cv2.imwrite("gray.jpg",gray_image)

# 阈值反二值化+形态学闭运算
res,thresh_img=cv2.threshold(blurM,135,255,cv2.THRESH_BINARY_INV)
kernel = np.ones((5,5),np.uint8) 
closing= cv2.morphologyEx(thresh_img,cv2.MORPH_CLOSE,kernel,iterations=2)
cv2.imwrite("result3.jpg",closing)

# 轮廓检测
contours, hierarchy = cv2.findContours(closing.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 有效轮廓过滤
valid_wbc = []
min_area = 200
max_area = 3000
for cnt in contours:
    area = cv2.contourArea(cnt)
    if min_area < area < max_area:
        valid_wbc.append(cnt)

# 可视化与计数
wbc_count = len(valid_wbc)
for i, cnt in enumerate(valid_wbc, 1):
    cv2.drawContours(output, [cnt], -1, (0,255,0), 2)
    M = cv2.moments(cnt)
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])
    cv2.putText(output, str(i), (cX-10, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 2)

cv2.putText(output, f"WBC Count: {wbc_count}", (20,40), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (255,0,0), 3)
cv2.imwrite("wbc_count_result.jpg", output)
print(f"检测到白细胞总数:{wbc_count}")

注意:代码中min_area、max_area、二值化阈值135都需要根据你自己的数据集调整,调整到和人工计数结果误差最小时即可固定参数批量处理。

内容的提问来源于stack exchange,提问作者Mohamed Ragih

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:36:26