如何用Python3.11与scikit-image去除培养皿外围假阳性保留内部菌落?
批量去除培养皿扫描图外围假阳性区域
问题背景
我需要处理随时间变化的培养皿扫描图像,分析菌落的生长速率、出现时间等统计数据。目前已完成以下步骤:
- 读取图像并转为灰度图
- 通过中值滤波处理
- 阈值分割得到二值图
当前实现代码:
# Reading image and gray scaling import skimage.io import skimage.color import matplotlib.pyplot as plt test = skimage.io.imread("C:/Users/user/Documents/PythTestImg/img016.tif") graytest = skimage.color.rgb2gray(test) fig, ax = plt.subplots() plt.imshow(graytest, cmap='gray') plt.show() # Median filter from skimage.morphology import disk from skimage.filters import median d = disk(radius=2) blurredtest = median(graytest, d) fig, ax = plt.subplots() plt.imshow(blurredtest, cmap='gray') plt.show() # Histogram creation import numpy as np histogram, bin_edges = np.histogram(blurredtest, bins=256, range=(0.0, 1.0)) fig, ax = plt.subplots() plt.plot(bin_edges[0:-1], histogram) plt.title("Grayscale Histogram") plt.xlabel("grayscale value") plt.ylabel("pixels") plt.xlim(0, 1.0) plt.show() # Thresholding section # t = skimage.filters.threshold_otsu(blurredtest) # print("Found automatic threshold t = {}.".format(t)) t = 0.93 finaltest = blurredtest > t fig, ax = plt.subplots() plt.imshow(finaltest, cmap="gray") plt.show()
当前结果已分离出白色菌落,但圆形培养皿外围存在假阳性区域(尤其是大块白色区域)。手动删除矩阵值的方式无法批量高效处理,尝试过霍夫变换和边缘检测但参数设置未达预期,需要在保留内部菌落的前提下,选择性去除培养皿外围的假阳性,使用环境为PyCharm、Python 3.11和scikit-image。
解决方案:圆形掩码过滤法
核心思路是精准定位培养皿的圆形区域,生成仅覆盖内部的掩码,通过掩码与二值图的逻辑运算剔除外围假阳性,完全适配批量处理。
1. 边缘检测提取培养皿轮廓
先对模糊后的灰度图做Canny边缘检测,为后续圆检测提供清晰轮廓:
from skimage import feature # sigma值根据图像噪声调整,越大边缘越平滑,噪声越少 edges = feature.canny(blurredtest, sigma=3)
2. 霍夫圆检测定位培养皿
通过霍夫圆检测锁定培养皿的圆心和半径,重点是设置合理的半径范围:
from skimage.transform import hough_circle, hough_circle_peaks import numpy as np # 估算培养皿的像素半径范围,根据图像实际尺寸调整 radius_range = np.arange(200, 300, 2) # 执行霍夫圆检测 hough_radii, hough_centers = hough_circle(edges, radius_range) # 获取最匹配的圆形(即培养皿) accums, cx, cy, radii = hough_circle_peaks(hough_radii, hough_centers, radius_range, total_num_peaks=1)
3. 生成培养皿内部掩码
基于检测到的圆心和半径,创建仅内部区域为True的二值掩码:
mask = np.zeros_like(finaltest) # 利用距离公式生成圆形掩码 y, x = np.ogrid[:mask.shape[0], :mask.shape[1]] distance_from_center = np.sqrt((x - cx)**2 + (y - cy)**2) mask[distance_from_center <= radii] = True
4. 过滤外围假阳性
将原始二值图与掩码做逻辑与运算,保留内部菌落,剔除外围假阳性:
cleaned_test = finaltest & mask # 展示处理后的结果 fig, ax = plt.subplots() plt.imshow(cleaned_test, cmap="gray") plt.show()
批量处理优化建议
- 若所有图像的培养皿尺寸、位置差异小,可固定半径范围;若差异大,可先用
skimage.measure.find_contours提取最大连通区域,再计算圆心和半径。 - 将上述步骤封装为函数,遍历图像文件夹实现批量自动处理。
参数调试技巧
- Canny边缘检测的
sigma:图像噪声多则调大,轮廓不清晰则调小。 - 霍夫圆检测的
radius_range:先查看图像尺寸估算培养皿像素半径,缩小范围可提升检测精度与速度。 - 若霍夫圆检测不稳定,可先通过Otsu自动阈值分割灰度图,再提取面积最大的连通区域作为培养皿,生成对应掩码。
内容的提问来源于stack exchange,提问作者DAVID VAYSBERG
相关产品推荐
相关产品推荐

