第四章:信号处理基础——拉曼散射信号的提取与去噪

各位同学,欢迎来到信号处理这一章。说实话,很多做光纤测温的朋友,硬件搭得漂漂亮亮,最后卡在信号处理上。我当年第一次搭DTS系统时,看着示波器上那堆毛刺,差点以为传感器坏了。后来才明白——信号处理,才是决定系统精度的关键。

4.1 拉曼散射信号的Stokes与Anti-Stokes提取

先说说最基础的事。拉曼散射光里,有两个关键成分:Stokes光和Anti-Stokes光。Stokes光波长比入射光长,Anti-Stokes光波长比入射光短。温度信息,就藏在它们的强度比里。

怎么提取呢?我习惯用带通滤波器加解调的方式。具体来说,分三步:

  1. 光电转换:APD或PMT把光信号变成电信号
  2. 带通滤波:分别提取Stokes和Anti-Stokes对应的频率成分
  3. 同步解调:用参考信号做相敏检测,把有用信号从噪声里捞出来

这里有个坑——两个通道的增益必须匹配。我曾经因为APD偏压没调好,Stokes通道增益比Anti-Stokes高了3dB,算出来的温度直接偏了5度。嗯,后来我加了个自动增益校准环节,每10分钟自检一次。

核心公式:温度T与拉曼强度比R的关系

R = (I_Anti / I_Stokes) ∝ exp(-hΔν / kT)

其中h是普朗克常数,Δν是拉曼频移,k是玻尔兹曼常数。说白了,测出强度比,就能反推出温度。

4.2 累加平均去噪算法

单次采集的信号,信噪比通常很差。你想想看,拉曼散射本身就很弱,再加上APD的暗电流噪声、放大器的热噪声……信号经常淹没在噪声里。

怎么办?累加平均。这是最朴素也最有效的办法。

原理很简单:噪声是随机的,均值趋近于零。信号是确定的,累加后线性增长。累加N次,信噪比提升√N倍。

// 累加平均伪代码
#define N 1000  // 累加次数
double sum_stokes[1024] = {0};
double sum_anti[1024] = {0};

for (int i = 0; i < N; i++) {
    acquire_frame(stokes, anti);  // 采集一帧
    for (int j = 0; j < 1024; j++) {
        sum_stokes[j] += stokes[j];
        sum_anti[j] += anti[j];
    }
}

// 取平均
for (int j = 0; j < 1024; j++) {
    avg_stokes[j] = sum_stokes[j] / N;
    avg_anti[j] = sum_anti[j] / N;
}

我的经验:N不是越大越好。N=1000时,信噪比提升约31倍,但采集时间也长了1000倍。对于静态测温,N取500-2000合适。对于动态测温(比如监测电缆发热),N取100-200就够了,否则跟不上温度变化。

4.3 滑动平均滤波

累加平均做完后,信号还是会有一些毛刺。这时候就该滑动平均上场了。

滑动平均,说白了就是取一个窗口,窗口内的数据求平均,然后窗口滑动。窗口宽度m越大,平滑效果越好,但空间分辨率会下降。

// 滑动平均实现
void moving_average(double *input, double *output, int len, int window) {
    int half = window / 2;
    for (int i = 0; i < len; i++) {
        double sum = 0;
        int count = 0;
        for (int j = i - half; j <= i + half; j++) {
            if (j >= 0 && j < len) {
                sum += input[j];
                count++;
            }
        }
        output[i] = sum / count;
    }
}

窗口宽度怎么选?我一般这样定:

应用场景窗口宽度(采样点)空间分辨率损失
短距离测温(<1km)3-50.5-1m
中距离测温(1-5km)7-151-3m
长距离测温(>5km)15-313-6m

注意:滑动平均会模糊温度突变点。比如电缆上有个局部热点,窗口太宽会把热点抹平。我曾经吃过这个亏——客户说测温不准,查了半天,原来是滑动窗口设了31点,把5米长的热点给平均成温升只有实际的一半。

4.4 差分衰减补偿

光纤是有损耗的。光在光纤里传播,距离越长,信号越弱。Stokes和Anti-Stokes的衰减系数还不一样,这就导致远端温度计算出现偏差。

差分衰减补偿,就是把这个偏差纠正回来。

具体做法:

  1. 先测量光纤的衰减曲线(用OTDR原理)
  2. 分别得到Stokes和Anti-Stokes的衰减系数α_s和α_a
  3. 对每个距离点的信号做补偿:
// 差分衰减补偿
double compensate(double raw_signal, double distance, double alpha) {
    // alpha单位:dB/km,distance单位:km
    double loss = alpha * distance;  // 总衰减dB
    double gain = pow(10, loss / 10);  // 转为线性增益
    return raw_signal * gain;
}

// 实际使用时,对Stokes和Anti-Stokes分别补偿
double comp_stokes = compensate(raw_stokes, dist, alpha_stokes);
double comp_anti = compensate(raw_anti, dist, alpha_anti);

关键点:补偿后的强度比R_comp = comp_anti / comp_stokes,这个比值才真正反映温度。如果不做补偿,远端温度会显示偏高——因为Anti-Stokes衰减更快,比值虚高。

我记得有一次在现场调试,30公里长的光纤,远端温度显示比实际高了8度。排查了半天,发现是光纤弯曲处衰减异常,补偿系数没跟上。后来我加了个自适应衰减追踪算法,每隔1公里重新校准一次衰减系数,问题就解决了。

知识体系总览

下面这张图,把本章的核心逻辑串起来了:

拉曼测温信号处理流程 ① 光信号采集 APD/PMT光电转换 Stokes + Anti-Stokes ② 信号提取 带通滤波 同步解调 ③ 累加平均 N次采集取平均 信噪比提升√N倍 ④ 滑动平均 窗口平滑去毛刺 注意空间分辨率 ⑤ 差分衰减补偿 α_s和α_a分别补偿 消除距离偏差 ⑥ 温度计算 强度比→温度映射 输出温度曲线 整个流程:光信号 → 提取 → 去噪 → 平滑 → 补偿 → 算温度 关键参数权衡 累加次数N ↑ → 信噪比↑ 但响应速度↓ 滑动窗口m ↑ → 平滑效果↑ 但空间分辨率↓

这张图把整个信号处理链路画清楚了。从光信号进来,到温度曲线出去,中间每一步都有讲究。你想想看,任何一个环节没做好,最终温度都可能差好几度。

好了,这一章的内容就这些。信号处理是个熟能生巧的活,多调参数、多看波形,慢慢就有感觉了。


专注资料整理