求简单Python区域生长图像分割工具,实现灰度图按像素相似度区域划分
基于灰度容差的区域分割解决方案
你的需求属于典型的基于灰度相似度的连通域分割场景,不需要使用复杂度高、参数调整麻烦的 watershed 算法,以下两个现成方案可直接满足要求:
方案1:OpenCV 实现(执行效率最高)
直接调用内置的漫水填充接口,容差参数可直接自定义,自动保证每个像素仅归属一个区域:
import cv2 import numpy as np # 读取单通道灰度图 gray_img = cv2.imread("input_gray.png", cv2.IMREAD_GRAYSCALE) h, w = gray_img.shape # 初始化分割标签矩阵,0代表未标记像素 seg_result = np.zeros((h, w), dtype=np.int32) current_region_id = 1 # 自定义容差:区域内像素和种子点像素的差值最大不超过该值 similarity_tolerance = 8 for y in range(h): for x in range(w): if seg_result[y, x] == 0: # 漫水填充标记符合容差的连通区域 cv2.floodFill( image=gray_img, mask=None, seedPoint=(x, y), newVal=current_region_id, loDiff=similarity_tolerance, upDiff=similarity_tolerance ) current_region_id += 1
- 优化建议:可在每次填充后统计区域面积,过滤掉像素数过少的噪点区域
方案2:scikit-image 实现(无需额外安装OpenCV依赖)
使用内置的flood接口实现相同逻辑,适合已经在使用skimage生态的场景:
import numpy as np from skimage.io import imread from skimage.segmentation import flood # 读取灰度图,默认输出为0-1归一化值 gray_img = imread("input_gray.png", as_gray=True) h, w = gray_img.shape seg_result = np.zeros((h, w), dtype=np.int32) current_region_id = 1 # 容差需要和0-1的灰度范围匹配,比如对应8bit的容差8,这里设置为8/255≈0.031 similarity_tolerance = 0.03 for y in range(h): for x in range(w): if seg_result[y, x] == 0: region_mask = flood(gray_img, (y, x), tolerance=similarity_tolerance) seg_result[region_mask] = current_region_id current_region_id += 1
补充说明
你之前使用无标记的watershed效果差是正常的:无markers输入时watershed会把梯度图所有局部极小值作为种子点,大概率产生严重过分割,该算法本身就不适合你当前的纯灰度相似度分割场景。
内容的提问来源于stack exchange,提问作者Xanshiz
相关产品推荐
相关产品推荐

