如何对光谱数据执行橡皮筋校正?

信息处理 频谱 Python 预处理 r
2021-12-23 12:25:18

我基本上了解了橡皮筋/基线校正的工作原理。

  1. 给定的光谱被分成 (N) 个范围。
  2. 确定每个范围内的最低点。
  3. 初始基线是由这些点构建的。
  4. 现在,频谱上的所有点都由当前范围内的最低点与基线最低点之间的差值绘制。

但是,有一些细微差别,我不知道如何处理。例如,如果其中一个点恰好位于两个范围之间的边界上,等等。

另外,我必须能够证明我正在编写的算法是一个可靠的算法,并且可以被其他作品或科学论文引用。

如果有人能给我一些参考,我会很高兴。

4个回答

这可以在R或中轻松完成Python有经过充分测试的功能可用,因此您不必担心任何界限或细微差别。此外,两者都是免费的,并且在科学家中很受欢迎。

R的解决方案

有一个特殊的包来处理光谱数据,称为hyperSpec橡皮筋基线校正已经在那里实现(功能spc.rubberband)。所有详细信息都在文档中突出显示。用法很简单:

require(hyperSpec)
spc <- read.spe("paracetamol.SPE")
baseline <- spc.rubberband(spc)

corrected <- spc - baseline

在此处输入图像描述

Python的解决方案

python 没有(据我所知)开箱即用的解决方案,但您可以使用scipy.spatial.ConvexHull函数来查找在光谱周围形成凸包的所有点的索引。假设频谱包含在xy数组中:

import numpy as np
from scipy.spatial import ConvexHull

def rubberband(x, y):
    # Find the convex hull
    v = ConvexHull(np.array(zip(x, y))).vertices

数组v包含顶点的索引,排列在逆时针方向,例如[892, 125, 93, 0, 4, 89, 701, 1023]我们必须提取v上升的部分,例如 0-1023。

    # Rotate convex hull vertices until they start from the lowest one
    v = np.roll(v, -v.argmin())
    # Leave only the ascending part
    v = v[:v.argmax()]

    # Create baseline using linear interpolation between vertices
    return np.interp(x, x[v], y[v])

现在基线被纠正如下:

y = y - rubberband(x, y)

在 python 中使用 Modpoly、Imodpoly 和 Zhang 拟合算法的解决方案。

Python 库 BaselineRemoval 具有 Modpoly、IModploy 和 Zhang 拟合算法,当您将原始值作为 python 列表或 pandas 系列输入并指定多项式次数时,可以返回基线校正结果。将库安装为pip install BaselineRemoval. 下面是一个例子

from BaselineRemoval import BaselineRemoval

input_array=[10,20,1.5,5,2,9,99,25,47]
polynomial_degree=2 #only needed for Modpoly and IModPoly algorithm

baseObj=BaselineRemoval(input_array)
Modpoly_output=baseObj.ModPoly(polynomial_degree)
Imodpoly_output=baseObj.IModPoly(polynomial_degree)
Zhangfit_output=baseObj.ZhangFit()

print('Original input:',input_array)
print('Modpoly base corrected values:',Modpoly_output)
print('IModPoly base corrected values:',Imodpoly_output)
print('ZhangFit base corrected values:',Zhangfit_output)

Original input: [10, 20, 1.5, 5, 2, 9, 99, 25, 47]
Modpoly base corrected values: [-1.98455800e-04  1.61793368e+01  1.08455179e+00  5.21544654e+00
  7.20210508e-02  2.15427531e+00  8.44622093e+01 -4.17691125e-03
  8.75511661e+00]
IModPoly base corrected values: [-0.84912125 15.13786196 -0.11351367  3.89675187 -1.33134142  0.70220645
 82.99739548 -1.44577432  7.37269705]
ZhangFit base corrected values: [ 8.49924691e+00  1.84994576e+01 -3.31739230e-04  3.49854060e+00
  4.97412948e-01  7.49628529e+00  9.74951576e+01  2.34940300e+01
  4.54929023e+01

可能有很多技术。你的想法对我来说似乎很好。

另外两个想法:

  1. 对数据进行 FFT 并滤除最低频率。这也消除了基线调制。当然,您必须手动或根据数据的有根据的猜测找到正确的过滤器宽度。

  2. 使用具有多个长波长的余弦函数并对数据进行线性拟合。您还可以通过简单的过滤器或通过使用信号强度对数据点进行加权来剔除峰值。

[编辑 2018/03/24] 自从回答以来,已经记录了光谱数据的几种用途

如果您的光谱峰值相对较好,并且在具有更多低频行为的基线之上几乎为正,我建议尝试BEADS (Baseline Estimation And Denoising w/ Sparsity),一种基于数据稀疏性的算法和它的一些衍生物。它适用于色谱数据。Matlab 代码可用BEADS 页面收集 R 或 C++ 代码,以及已知用途在这里,您可以找到拉曼光谱、天文高光谱星系光谱、X 射线吸收光谱 (XAS)、X 射线衍射 (XRD) 和 XAS/XRD 组合测量的用途。

具有模拟基线的色谱

基线和噪声校正