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

如何使用OpenCV与Python实现图像中重叠颗粒的分割计数

重叠颗粒分割计数方案(OpenCV+Python实现)

样本参考图像

图像1
图像2

核心方案说明

针对颗粒重叠粘连无法直接计数的场景,采用「距离变换+分水岭分割」的组合方案实现精准分割,是OpenCV生态下处理这类问题的最优选择,不需要额外引入深度学习框架就能达到不错的计数准确率。

分步实现逻辑

  • 图像预处理:读入图像后转灰度,用高斯模糊消除随机噪点,降低后续误判概率
  • 二值化分割:用大津法(OTSU)自动计算阈值完成前后景分离,可配合形态学开运算消除小型噪点
  • 确定前景标记:对二值图做距离变换,取距离变换结果的70%(可根据实际效果调整)作为阈值,得到的就是100%属于单个颗粒核心的确定前景
  • 确定背景标记:对二值图做3-5次形态学膨胀,膨胀后得到的区域减去确定前景,就是无法判断属于前景还是背景的未知区域
  • 连通域标记:对确定前景做连通域检测,给每个独立的颗粒核心分配唯一的数字标签
  • 执行分水岭分割:把连通域标记结果作为输入传入分水岭算法,算法会自动把未知区域划分给最近的颗粒核心,同时生成不同颗粒之间的分割边界
  • 计数统计:统计最终标记结果中不同非负标签的数量,就是颗粒的总个数

完整代码示例

import cv2
import numpy as np

# 读入图像
img = cv2.imread('你的图像路径.png')
# 转灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 高斯模糊降噪
blur = cv2.GaussianBlur(gray, (5,5), 0)
# 大津法二值化,若颗粒颜色比背景深可去掉THRESH_BINARY_INV参数
ret, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

# 形态学开运算去噪
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations = 2)

# 确定背景:膨胀运算
sure_bg = cv2.dilate(opening, kernel, iterations=3)

# 距离变换获取确定前景
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
# 重叠度高的场景可把0.7调整为0.8左右
ret, sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)

# 计算未知区域
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)

# 连通域标记
ret, markers = cv2.connectedComponents(sure_fg)
# 分水岭要求标记从1开始,所以所有标记+1
markers = markers + 1
# 未知区域标记为0
markers[unknown==255] = 0

# 执行分水岭
markers = cv2.watershed(img, markers)
# 把边界标成红色方便观察
img[markers == -1] = [255,0,0]

# 统计颗粒数量:减去背景标签1
particle_count = len(np.unique(markers)) - 1
print(f"颗粒总数量:{particle_count}")

# 可视化分割结果
cv2.imshow('分割结果', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 04:36:02