- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在研究拉曼光谱,它通常有一个基线与我感兴趣的实际信息叠加。因此,我想估计基线贡献。为此,我实现了 this question 中的解决方案。
我确实喜欢那里描述的解决方案,并且给出的代码在我的数据上运行良好。计算数据的典型结果如下所示,其中红色和橙色线是基线估计:Typical result of baseline estimation with calculated data
问题是:我经常在 pandas DataFrame 中收集数千个光谱,每一行代表一个光谱。我当前的解决方案是使用 for 循环一次迭代一个频谱的数据。然而,这使得该过程相当缓慢。由于我对 python 相当陌生,而且由于 numpy/pandas/scipy 的帮助,我已经习惯了几乎不必使用 for 循环,因此我正在寻找一种解决方案,使得也可以省略这个 for 循环。然而,使用的稀疏矩阵函数似乎仅限于二维,但我可能需要三个,而且我还无法想到另一个解决方案。有人有想法吗?
当前代码如下所示:
import numpy as np
import pandas as pd
from scipy.signal import gaussian
import matplotlib.pyplot as plt
from scipy import sparse
from scipy.sparse.linalg import spsolve
def baseline_correction(raman_spectra,lam,p,niter=10):
#according to "Asymmetric Least Squares Smoothing" by P. Eilers and H. Boelens
number_of_spectra = raman_spectra.index.size
baseline_data = pd.DataFrame(np.zeros((len(raman_spectra.index),len(raman_spectra.columns))),columns=raman_spectra.columns)
for ii in np.arange(number_of_spectra):
curr_dataset = raman_spectra.iloc[ii,:]
#this is the code for the fitting procedure
L = len(curr_dataset)
w = np.ones(L)
D = sparse.diags([1,-2,1],[0,-1,-2], shape=(L,L-2))
for jj in range(int(niter)):
W = sparse.spdiags(w,0,L,L)
Z = W + lam * D.dot(D.transpose())
z = spsolve(Z,w*curr_dataset.astype(np.float64))
w = p * (curr_dataset > z) + (1-p) * (curr_dataset < z)
#end of fitting procedure
baseline_data.iloc[ii,:] = z
return baseline_data
#the following four lines calculate two sample spectra
wavenumbers = np.linspace(500,2000,100)
intensities1 = 500*gaussian(100,2) + 0.0002*wavenumbers**2
intensities2 = 100*gaussian(100,5) + 0.0001*wavenumbers**2
raman_spectra = pd.DataFrame((intensities1,intensities2),columns=wavenumbers)
#end of smaple spectra calculataion
baseline_data = baseline_correction(raman_spectra,200,0.01)
#the rest is just for plotting the data
plt.figure(1)
plt.plot(wavenumbers,raman_spectra.iloc[0])
plt.plot(wavenumbers,baseline_data.iloc[0])
plt.plot(wavenumbers,raman_spectra.iloc[1])
plt.plot(wavenumbers,baseline_data.iloc[1])
最佳答案
根据Christian K.的建议,我研究了背景估计的SNIP算法,详细信息可以参见例如here 。这是我的 python 代码:
import numpy as np
import pandas as pd
from scipy.signal import gaussian
import matplotlib.pyplot as plt
def baseline_correction(raman_spectra,niter):
assert(isinstance(raman_spectra, pd.DataFrame)), 'Input must be pandas DataFrame'
spectrum_points = len(raman_spectra.columns)
raman_spectra_transformed = np.log(np.log(np.sqrt(raman_spectra +1)+1)+1)
working_spectra = np.zeros(raman_spectra.shape)
for pp in np.arange(1,niter+1):
r1 = raman_spectra_transformed.iloc[:,pp:spectrum_points-pp]
r2 = (np.roll(raman_spectra_transformed,-pp,axis=1)[:,pp:spectrum_points-pp] + np.roll(raman_spectra_transformed,pp,axis=1)[:,pp:spectrum_points-pp])/2
working_spectra = np.minimum(r1,r2)
raman_spectra_transformed.iloc[:,pp:spectrum_points-pp] = working_spectra
baseline = (np.exp(np.exp(raman_spectra_transformed)-1)-1)**2 -1
return baseline
wavenumbers = np.linspace(500,2000,1000)
intensities1 = gaussian(1000,20) + 0.000002*wavenumbers**2
intensities2 = gaussian(1000,50) + 0.000001*wavenumbers**2
raman_spectra = pd.DataFrame((intensities1,intensities2),columns=np.around(wavenumbers,decimals=1))
iterations = 100
baseline_data = baseline_correction(raman_spectra,iterations)
#the rest is just for plotting the data
plt.figure(1)
plt.plot(wavenumbers,raman_spectra.iloc[0])
plt.plot(wavenumbers,baseline_data.iloc[0])
plt.plot(wavenumbers,raman_spectra.iloc[1])
plt.plot(wavenumbers,baseline_data.iloc[1])
它确实有效,并且看起来与基于非对称最小二乘平滑的算法同样可靠。它也更快。通过 100 次迭代,拟合 73 个真实的测量光谱大约需要 1.5 秒,结果总体良好,而相比之下,大约需要 1.5 秒。 2.2 对于非对称最小二乘平滑,所以是一种改进。
更好的是:所需的计算时间对于 3267 个真实光谱,使用 SNIP 算法只需 11.7 秒,而对于非对称最小二乘平滑则为 1 分 28 秒。这可能是由于 SNIP 算法没有使用任何 for 循环一次遍历每个频谱的结果。
A typical result of the SNIP algorithm with calculated examples is shown here 。
我对这个结果非常满意,感谢所有贡献者的支持!
更新:感谢 this question 中的 sascha ,我找到了一种使用不对称最小二乘平滑而不使用 for 循环迭代每个频谱的方法,基线校正函数如下所示:
def baseline_correction4(raman_spectra,lam,p,niter=10):
#according to "Asymmetric Least Squares Smoothing" by P. Eilers and H. Boelens
number_of_spectra = raman_spectra.index.size
#this is the code for the fitting procedure
L = len(raman_spectra.columns)
w = np.ones(raman_spectra.shape[0]*raman_spectra.shape[1])
D = sparse.block_diag(np.tile(sparse.diags([1,-2,1],[0,-1,-2],shape=(L,L-2)),number_of_spectra),format='csr')
raman_spectra_flattened = raman_spectra.values.ravel()
for jj in range(int(niter)):
W = sparse.diags(w,format='csr')
Z = W + lam * D.dot(D.transpose())
z = spsolve(Z,w*raman_spectra_flattened,permc_spec='NATURAL')
w = p * (raman_spectra_flattened > z) + (1-p) * (raman_spectra_flattened < z)
#end of fitting procedure
baseline_data = pd.DataFrame(z.reshape(number_of_spectra,-1),index=raman_spectra.index,columns=raman_spectra.columns)
return baseline_data
这种方法基于将所有稀疏矩阵组合成一个 block 对角稀疏矩阵。这样,无论您有多少个光谱,您都只需调用 spsolve 一次。这导致在 593 毫秒内对 73 个真实光谱进行基线校正(比 SNIP 快),在 32.8 秒内对 3267 个真实光谱进行基线校正(比 SNIP 慢)。我希望这对将来的人有用。
关于python - 光谱数据的基线校正,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57350711/
我试图通过叠加更新的(更详细的)卫星图像(我从 {leaflet} 包中获取)来改善 Rayshader 的外观,但叠加层不匹配与 3D 渲染。 理想情况下,我正在寻找可以获取全局卫星图像的开源解决方
我想构建一个由单个数字组成的常量数组(1..200)来制作一个“查找表”,以将值为 1 - 200 的滚动条的位置转换为用于对图像应用 Gamma 校正的值。 第一个数组值的值在 7.0 - 9.9
我尝试对图像进行一些简单的 Gamma 校正。起初,我尝试使用 Matlab,然后将其应用于 opencv。但我得到不同的结果。下面是部分代码。代码哪里出错了? 在matlab中: for i=1:r
我使用 DirectXTex 库捕获 DX11 游戏的屏幕截图并将其保存到文件中。问题是当我将它保存为 jpeg 时效果很好,但如果我将它保存为 png 图像会变得非常明亮并被洗掉。我使用 Tweak
我正在尝试使用以下代码检测图像中ID卡的边界。关键是我使用的 Gamma 值。我使用2或3的值(假设我希望卡在背景下突出显示)。使用背景较浅或与卡片颜色本身一样浅的照片时遇到问题。请看下面的图片..第
我正在进行立体视觉设置,机翼上方安装了 2 个摄像头。左摄像头向内倾斜几度,而右摄像头与机翼平行。所有可用图像 here 然后使用(剪切和粘贴,但不按原样编译) // performing stere
我正在尝试解决有关 NFA 的问题。指令如下:字母{a, b, c}。 • L1 是最后一个字符与倒数第五个字符相同的所有字符串。例如,应该接受字符串 aaacbacbca,因为倒数第五个字符和最后一
我尝试使用 qt 更改图像的 Gamma,但没有得到理想的结果。这是我的代码: QImage Filters::aply_filtre_gamma(QImage image){ // (std:
我需要对 Y'CbCr 空间中的图像进行 Gamma 校正,以便在图像中的饱和和饥饿区域中显示细节,我想知道是否需要调整色度子 channel ? 我知道如果我让亮度 channel 像素挨饿,如果我
我不了解opencv中hog.cpp中的 Gamma 校正代码,我经历了一些链接here与opencv hog.cpp中的代码不匹配 Mat_ _lut(1, 256); const float* l
根据本页http://www.w3schools.com/cssref/css3_pr_filter.asp有对比度、亮度、色调、饱和度等。但没有明确访问 Gamma 。有没有办法用现有的 CSS3
我进行了超几何分析(使用 Python 脚本)来研究 GO-terms 在基因子集中的富集。我的输出示例如下: GO00001 1500 300 200 150 5.39198144708e-7
我使用 Opencv 编写了一个 Android 应用程序,我的图像处理算法需要对检测到的矩形进行正确的旋转,因此作为该过程的开始,我 将最大的矩形检测为 RotatedRect。 获取矩形的旋转角度
我正在使用 OpenCV 校准和校正立体声系统。我有一个眼睛会聚的立体相机,实际上我按以下顺序运行这些功能: for(int j=0; j < ChessBoard.numSquares; j++)
我会对图像使用 Gamma 校正。因此,我必须使用 G = 0.6 为源图像的每个像素强度赋值。我有问题,因为目标图像完全错误。当我从源图像中获取像素时,可能会遇到转换问题。这是我的代码: #incl
我正在构建一个 Android 应用程序,为用户提供一些图像处理功能。但在应用任何图像转换功能之前,我想进行 Gamma 校正以改善图像。我知道如何执行 Gamma 校正,但我不知道要使用什么 Gam
我在 Windows 10 上使用 SDL2 创建 OpenGL 上下文,但是当我尝试在 Intel UHD 630 上获取帧缓冲区附件颜色编码时,我收到了无效操作错误。在我的 Nvidia Gefo
我有RGB数据和Gamma校正比例 我可以用下面的来计算吗 R = pow(R, 1/Gamma) G = pow(G, 1/Gamma) B = pow(B, 1/Gamma) 或 Gamma 校正
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
自 Snow Leopard 以来,QTKit 现在从 QTMovies frameImageAtTime:withAttributes:error: 等函数返回颜色校正后的图像数据。给定未压缩的 A
我是一名优秀的程序员,十分优秀!