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

如何消除DIY图像荧光计暗场(无光)采集图像中的椒盐噪声

暗场椒盐噪声消除方案

算法优化方案(直接可落地,兼容树莓派/Jetson TX2)

  • 中值滤波去椒盐噪声:优先选3x3核的中值滤波,是椒盐噪声的针对性处理方案,计算量极低,树莓派实时运行无压力,也不会过度模糊有效荧光信号。
  • 多帧暗场基线校正:不要单帧采集暗场基线,启动正式测量前连续采集10~20帧暗场图像,逐像素取中位数生成固定暗场模板,后续所有测量帧先减去该模板再计算平均强度,可同时消除固定pattern噪声和随机椒盐噪声的影响。
  • 低阈值截断:统计暗场下掩模区域的噪声像素值分布,设置合理的截断阈值(比如8位图像下小于5的像素直接置0),暗场噪声普遍低于该阈值,不会影响后续有效荧光信号的计算。

硬件优化方案(进一步降低噪声底)

  • 调整相机参数:当前CAP_PROP_BRIGHTNESS设为5,可尝试下调到1~3,很多工业相机的亮度参数会主动拉高暗场增益,放大噪声。
  • 优化供电:给USB相机单独供电,避免树莓派USB口供电不足引入的随机噪点。
  • 补全遮光:检查设备外壳的漏光缝隙,用遮光棉填补,排除微小环境光漏入导致的暗场非全黑问题。

现有代码修改示例

import numpy as np
import cv2
import sys
import csv

cap = cv2.VideoCapture(0 + cv2.CAP_V4L)
cap2 = cv2.VideoCapture(2 + cv2.CAP_V4L) # Thermal camera

rows = 640
cols = 480

# 相机参数设置
cap.set(cv2.CAP_PROP_FRAME_WIDTH, cols)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, rows)
cap.set(cv2.CAP_PROP_CONVERT_RGB, 0) # turn off RGB conversion
cap.set(cv2.CAP_PROP_BRIGHTNESS, 2) # 下调亮度降低噪声
cap.set(cv2.CAP_PROP_FPS, 30)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc(*'Y16 '))

# 读取掩模
binary = cv2.imread('Masked_Image.png')
binary = binary[:,:,1]

# ========== 新增:采集多帧暗场模板 ==========
dark_frames = []
print("正在采集暗场基线,请保持关灯状态...")
for i in range(15): # 采集15帧暗场
    _, frame = cap.read()
    bf8 = np.array(frame//16, dtype = np.uint8)
    dark_frames.append(bf8)
# 逐像素取中位数生成暗场模板
dark_template = np.median(np.array(dark_frames), axis=0).astype(np.uint8)
# 可选:对暗场模板做中值滤波进一步去噪
dark_template = cv2.medianBlur(dark_template, 3)
print("暗场基线采集完成")

original_stdout = sys.stdout

while True:
    _, frame = cap.read()
    _, frame2 = cap2.read()

    bf8 = np.array(frame//16, dtype = np.uint8)
    # ========== 新增:暗场校正 + 中值滤波去噪 ==========
    # 减去暗场模板,负值置0
    bf8 = cv2.subtract(bf8, dark_template)
    # 中值滤波去椒盐噪声
    bf8 = cv2.medianBlur(bf8, 3)
    # 可选:低阈值截断,小于3的像素置0
    bf8[bf8 < 3] = 0
    
    im3 = cv2.bitwise_and(bf8,binary)
    im3[binary==0] = 0

    # 后续原有逻辑不变
    bf8_2 = cv2.normalize(im3, None, 0.0, 1.0, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
    bf8_2_color = cv2.applyColorMap(im3, cv2.COLORMAP_JET)
    bf8_3_color = cv2.applyColorMap(frame2, cv2.COLORMAP_JET)
    cv2.imwrite('Masked_Image.png', binary)

    cv2.imshow('Masked_Image', bf8_2)
    cv2.imshow("lepton", cv2.resize(bf8_3_color, (640, 480)))
    cv2.imshow("Opencv Video See3Cam_CU51 Color", bf8_2_color)
    cv2.imshow('Opencv Binary Image', binary)
    print('Pixels =', cv2.countNonZero(im3))
    print('Mean =', cv2.mean(bf8_2, im3)[:1])
    print('Standard Deviation =', cv2.meanStdDev(bf8_2, im3)[:1])

    with open('Results1.csv', 'a') as csvfile:
        fieldnames = ['Mean']
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        writer.writerow({'Mean': cv2.mean(bf8_2, im3)[:1]})

    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:57:01