如何使用OpenCV与Python实现图像中重叠颗粒的分割计数
重叠颗粒分割计数方案(OpenCV+Python实现)
样本参考图像


核心方案说明
针对颗粒重叠粘连无法直接计数的场景,采用「距离变换+分水岭分割」的组合方案实现精准分割,是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
相关产品推荐
相关产品推荐

