简单计算信噪比

信噪比是评估一个新的成像探针或者成像方法的重要指标之一。

最近看到一篇文章1,用到一种比较直观简单的信噪比估计方式。其基本思路是:

  1. 选取信号区域和背景区域ROI若干

  2. 假定信号区域的信号强度实际是真实强度与背景噪声强度的叠加,记作 SIG+BACK

  3. 然后将信号区域的 SIG+BACK 减去背景区域的 BACK 得到真实的信号强度SIG

  4. 这个真实的信号强度 SIG 作为一个估计值,其 uncertainty 上限可通过 SIG+BACKBACK 的方差之和开平方来计算

  5. 信噪比就是 SIGBK 的比值,同理,这个信噪比作为估计值,uncertainty 上限也可以通过一个公式来计算。

Pasted-image-20240904104834.png-ee6b39da71.png

文章中关于该方法的描述节选如上图所示。果然还是用公式来描述更加清晰简洁。这里的计算非常简单,基本是初中数学难度。

接下来,我尝试将这套方法转换为一个python函数,方便后续有需要的时候调用。对于这个函数而言,首先给一个名字叫做 calculateSNR,计算信噪比。然后要想想这个函数的输入是啥?其实输入SIG+BACKBACK 的数据就行。这个函数的输出,就是上述所有计算的中间结果,可以存到一个字典中。

更具体地,对于输入数据,它需要求平均,那必然不是一个数值,而得是一串数值。为了方便,我还是使用 pd.DataFrame 作为输入。从图像选取ROI中提取所有像素可参考👇

文章收集ROI内的像素值

如果想收集图像ROI中所有像素值且无需保留矩阵结构,可以使用以下函数。 ROI记录通常包含的是ROI轮廓线条的锚点的坐标,我们实际上想获得是这个ROI区域内的所有像素的值。这里使用了 scikit image 中的 draw.polygon 函数,这个函数输入锚点坐标后,会返回该区域内所有位置的索引...

此例中计算信噪比的函数具体代码如下:

import pandas as pd
import numpy as np
def calculateSNR(a:pd.DataFrame, b:pd.DataFrame)->dict:
'''
a: 信号区域的dataframe,必须包含 intensity 列
b:背景区域的dataframe
'''
sig_bk = a.intensity.mean()
print("MEAN_SIG+BACK", sig_bk)
bk = b.intensity.mean()
print("MEAN_BACK", bk)
sig = sig_bk - bk
print("MEAN_SIG", sig)
sig_bk_std = a.intensity.std()
print("SD_SIG+BACK", sig_bk_std)
bk_std = b.intensity.std()
print("SD_BACK", bk_std)
sig_std = np.sqrt(pow(sig_bk_std, 2)+pow(bk_std, 2))
print("SD_SIG", sig_std)
SNR = sig/bk
print("SNR", SNR)
SNR_std = SNR * np.sqrt(pow(sig_std/sig, 2) + pow(bk_std/bk, 2))
print("SD_SNR", SNR_std)
res = {
"MEAN_SIG+BACK": sig_bk,
"SD_SIG+BACK": sig_bk_std,
"MEAN_BACK": bk,
"SD_BACK": bk_std,
"MEAN_SIG": sig,
"SD_SIG": sig_std,
"SNR": SNR,
"SD_SNR": SNR_std,
}
return res

Footnotes

  1. Multiplex, Quantitative, High-Resolution Imaging of Protein:Protein Complexes via Hybridization Chain Reaction, ACS Chemical Biology, 2024. https://doi.org/10.1021/acschembio.3c00431