1

我的软件应该判断谱带,并给定谱带的位置,找到谱带的峰值点和宽度。

在此处输入图像描述

我学会了对图像进行投影找到每个峰的宽度


但我需要一种更好的方法来找到投影

我使用的方法将 1600 像素宽的图像(例如 1600X40)缩小为 1600 长的序列。理想情况下,我想使用相同的图像将图像减少到 10000 长的序列。

我想要更长的序列,因为 1600 点提供的分辨率太低。单个点会导致测量值有很大差异(如果一个带从 18 到 19 判断,则有 4% 的差异)。

如何从同一图像中获得更长的投影?

我使用的代码:https ://stackoverflow.com/a/9771560/604511

import Image
from scipy import *
from scipy.optimize import leastsq

# Load the picture with PIL, process if needed
pic         = asarray(Image.open("band2.png"))

# Average the pixel values along vertical axis
pic_avg     = pic.mean(axis=2)
projection  = pic_avg.sum(axis=0)

# Set the min value to zero for a nice fit
projection /= projection.mean()
projection -= projection.min()
4

2 回答 2

7

你想要做的叫做插值。Scipy 有一个 interpolate 模块,具有针对不同情况的一大堆不同的功能,看看这里,或者专门用于图像这里

是一个最近提出的问题,其中包含一些示例代码,以及显示发生了什么的图表。

但意识到插值不会使您的数据更准确非常重要,因此在这种情况下它对您没有帮助。

如果您想要更准确的结果,您需要更准确的数据。没有其他办法。您需要从更高分辨率的图像开始。(如果您重新采样或插值,您的结果将不太准确!)

更新 - 因为问题已经改变

@Hooked 提出了一个很好的观点。另一种思考方式是,您可以从光谱图像中的每个水平行生成 40 个图表(如您发布的图像中的较低图表),而不是立即平均(这确实会丢弃数据中的方差),所有这些图表将非常相似,但峰值位置、高度和宽度会有一些变化。您应该计算这 40 个图像中每个峰的位置、高度和宽度,然后结合这些数据(匹配 40 个图表中的峰),并使用适当的方差作为误差估计(对于峰位置、高度,和宽度),通过使用中心极限定理。这样您就可以充分利用您的数据。但是,我相信这是假设频谱图中的每一行之间有一定的独立性,这可能是也可能不是?

于 2012-06-13T07:07:59.190 回答
2

我想为@fraxel 的回答提供更多细节(渴望发表评论)。他是对的,你不能得到比你输入的更多的信息,但我认为它需要一些细节......

  1. 您正在投影您的数据1600x40 -> 1600似乎您正在丢弃一些数据。虽然在技术上是正确的,但投影的全部意义在于将高维数据带到低维。这只有在......
  2. 您的数据可以在较低维度中充分表示。如果我错了,请纠正我,但看起来您的数据确实是一维的,垂直轴是 x 轴上该特定点(波长?)的可变性的度量。
  3. 鉴于投影是有意义的,我们如何才能最好地总结每个特定波长点的数据?在我之前的回答中,您可以看到我取了每个点的平均值。在没有关于系统特定属性的其他信息的情况下,这是一个合理的一阶近似。
  4. 如果您愿意,您可以保留更多信息。下面我绘制了沿 y 轴的方差。这告诉我,当信号较高时,您的测量具有更大的可变性,而在信号较低时具有较低的可变性(这似乎很有用!): 在此处输入图像描述
  5. 那么需要做的是在投影之前决定你将如何处理那些额外的 40 像素数据。它们在物理上意味着一些东西,作为研究人员,您的工作是以有意义的方式解释和投射这些数据!

生成图像的代码如下,规范。数据取自您原始帖子的屏幕截图:

import Image
from scipy import *
from scipy.optimize import leastsq

# Load the picture with PIL, process if needed
pic         = asarray(Image.open("spec2.png"))

# Average the pixel values along vertical axis
pic_avg     = pic.mean(axis=2)
projection  = pic_avg.sum(axis=0)

# Compute the variance
variance = pic_avg.var(axis=0)

from pylab import *

scale = 1/40.

X_val = range(projection.shape[0])
errorbar(X_val,projection*scale,yerr=variance*scale)
imshow(pic,origin='lower',alpha=.8)
axis('tight')
show()
于 2012-06-13T14:14:49.333 回答