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

Python去除琼脂平板图像中类菌落噪声的预处理技术咨询

琼脂平板图像去噪与菌落计数优化方案

针对你遇到的“噪声与菌落形态相似,传统滤波/形态学操作无效”的问题,推荐以下几种Python实现的针对性方法:

1. 自适应阈值分割+连通域面积过滤

虽然噪声和菌落形态相似,但多数情况下噪声的面积远小于真实菌落。结合自适应阈值分割(应对光照不均)+ 连通域面积过滤,可以精准剔除小噪声:

import cv2
import numpy as np

# 读取图像
img = cv2.imread("Or1Om.png", cv2.IMREAD_GRAYSCALE)

# 自适应阈值分割(高斯加权)
thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

# 寻找连通域
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)

# 过滤小连通域(根据实际菌落大小调整面积阈值,比如这里设为50)
min_area = 50
filtered_img = np.zeros_like(thresh)
for i in range(1, num_labels):  # 跳过背景(标签0)
    if stats[i, cv2.CC_STAT_AREA] >= min_area:
        filtered_img[labels == i] = 255

# 显示结果
cv2.imshow("Filtered Result", filtered_img)
cv2.waitKey(0)

注:面积阈值需要根据你的实际图像调整,可通过统计真实菌落的最小面积确定。

2. 非局部均值去噪(Non-Local Means Denoising)

传统滤波只考虑局部邻域,非局部均值通过寻找图像中相似的像素块进行加权平均,对与菌落形态相似但分布零散的噪声效果更好:

import cv2

img = cv2.imread("Or1Om.png", cv2.IMREAD_GRAYSCALE)
# 非局部均值去噪(参数调整:h越大去噪越强,可能模糊菌落;templateWindowSize和searchWindowSize按需调整)
denoised_img = cv2.fastNlMeansDenoising(img, h=10, templateWindowSize=7, searchWindowSize=21)

# 后续可结合阈值分割提取菌落
thresh = cv2.threshold(denoised_img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
cv2.imshow("Non-Local Means Denoising", thresh)
cv2.waitKey(0)

建议先调整h值,找到去噪效果和菌落清晰度的平衡点。

3. 帧间时序分析去噪

由于是延时拍摄,真实菌落会随时间生长(面积/形态变化),而噪声在多帧中基本无变化。可以利用多帧差分或帧间一致性过滤噪声:

import cv2
import numpy as np

# 假设读取3帧延时图像(实际可根据你的序列调整)
frame1 = cv2.imread("frame1.png", cv2.IMREAD_GRAYSCALE)
frame2 = cv2.imread("frame2.png", cv2.IMREAD_GRAYSCALE)
frame3 = cv2.imread("frame3.png", cv2.IMREAD_GRAYSCALE)

# 计算帧间差异
diff1 = cv2.absdiff(frame1, frame2)
diff2 = cv2.absdiff(frame2, frame3)
# 取两帧差异的交集(只保留连续变化的区域,即菌落)
stable_diff = cv2.bitwise_and(diff1, diff2)

# 阈值化后过滤小区域
thresh = cv2.threshold(stable_diff, 20, 255, cv2.THRESH_BINARY)[1]
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)
filtered = np.zeros_like(thresh)
min_area = 30
for i in range(1, num_labels):
    if stats[i, cv2.CC_STAT_AREA] >= min_area:
        filtered[labels == i] = 255

cv2.imshow("Temporal Denoising", filtered)
cv2.waitKey(0)

这种方法能从根源上区分“静态噪声”和“动态生长的菌落”,是延时图像的特有优势。

4. 小样本深度学习分割(U-Net)

如果上述传统方法仍无效,可尝试用U-Net训练一个小型分割模型,仅需标注少量图像即可精准区分菌落和噪声:

# 示例用Keras实现简易U-Net(需提前准备标注数据)
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, concatenate

def build_unet(input_size=(256,256,1)):
    inputs = Input(input_size)
    # 编码器
    c1 = Conv2D(16, (3,3), activation='relu', padding='same')(inputs)
    c1 = Conv2D(16, (3,3), activation='relu', padding='same')(c1)
    p1 = MaxPooling2D((2,2))(c1)
    
    # 解码器
    u2 = UpSampling2D((2,2))(p1)
    u2 = concatenate([u2, c1])
    c2 = Conv2D(16, (3,3), activation='relu', padding='same')(u2)
    c2 = Conv2D(16, (3,3), activation='relu', padding='same')(c2)
    
    outputs = Conv2D(1, (1,1), activation='sigmoid')(c2)
    model = Model(inputs=[inputs], outputs=[outputs])
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    return model

# 训练(需替换为你的数据加载逻辑)
model = build_unet()
# model.fit(train_images, train_masks, epochs=20, batch_size=8)

# 预测
# test_img = cv2.imread("Or1Om.png", cv2.IMREAD_GRAYSCALE)/255.0
# test_img = np.expand_dims(test_img, axis=(0,-1))
# pred_mask = model.predict(test_img)[0,:,:,0]
# pred_mask = (pred_mask > 0.5).astype(np.uint8)*255

这种方法对形态高度相似的噪声/目标区分度最高,适合复杂场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 01:10:15