2つのスペクトル間のサブピクセルシフトを直接比較し、信頼できるエラーを取得


9

同じ天体の2つのスペクトルがあります。重要な質問はこれです:これらのスペクトル間の相対的なシフトを計算して、そのシフトで正確なエラーを取得するにはどうすればよいですか?

まだ私と一緒にいるなら、もう少し詳しく。各スペクトルは、x値(波長)、y値(光束)、および誤差を持つ配列になります。波長シフトはサブピクセルになります。ピクセルが等間隔に配置されており、スペクトル全体に適用される波長シフトが1つだけであると仮定します。したがって、最終的な答えは、0.35 +/- 0.25ピクセルのようなものになります。

2つのスペクトルは、簡単にモデル化できない(そして周期的ではない)かなり複雑な吸収特性(ディップ)によって区切られた、多くの特徴のない連続体になります。2つのスペクトルを直接比較する方法を見つけたいのですが。

すべての人の最初の本能は相互相関を行うことですが、サブピクセルシフトを使用すると、スペクトル間を補間する必要があります(最初にスムージングすることによって?)。また、エラーが正しくなるには厄介なようです。

私の現在のアプローチは、ガウスカーネルとのたたみ込みによってデータを平滑化し、平滑化された結果をスプライン化し、2つのスプライン化されたスペクトルを比較することですが、信頼できません(特にエラー)。

これを正しく行う方法を誰かが知っていますか?

これは、0.4ピクセルだけシフトされた2つのおもちゃのスペクトル(toy1.asciiおよびtoy2.asciiで書き出されます)を生成する短いpythonプログラムです。このおもちゃのモデルは単純なガウス機能を使用していますが、実際のデータは単純なモデルでは適合できないと想定しています。

import numpy as np
import random as ra
import scipy.signal as ss
arraysize = 1000
fluxlevel = 100.0
noise = 2.0
signal_std = 15.0
signal_depth = 40.0
gaussian = lambda x: np.exp(-(mu-x)**2/ (2 * signal_std))
mu = 500.1
np.savetxt('toy1.ascii', zip(np.arange(arraysize), np.array([ra.normalvariate(fluxlevel, noise) for x in range(arraysize)] - gaussian(np.arange(arraysize)) * signal_depth), np.ones(arraysize) * noise))
mu = 500.5
np.savetxt('toy2.ascii', zip(np.arange(arraysize), np.array([ra.normalvariate(fluxlevel, noise) for x in range(arraysize)] - gaussian(np.arange(arraysize)) * signal_depth), np.ones(arraysize) * noise))

私が正しく理解していれば、問題は画像のレジストレーションと同じように聞こえますが、1つの軸に線形のサブピクセルシフトがあるだけです。おそらく、位相相関などの標準的な画像レジストレーション手法を試してください。
ポールR

1つの信号に純粋な遅延がある場合(つまり、話す波長パラメーターのシフト)、時間遅延を周波数領域の線形位相オフセットに変換するフーリエ変換プロパティを利用できる場合があります。これは、2つのサンプルが異なる測定ノイズや干渉によって破損していない場合に機能します。
Jason R

1
このスレッドはuseful-かもしれdsp.stackexchange.com/questions/2321/...
ジム・クレイ

1
テストする実際のデータはありますか?指定したノイズ値は多すぎるため、相互相関をサブサンプルで正確にすることができません。これは、例えば、それはノイズ2.0と(プロットのx軸上= 1000.7)0.7オフセットのいくつかの実験で見つけるものである:i.stack.imgur.com/UK5JD.png
endolith

回答:


5

相互相関を使用し、ピークを補間することはうまくいくと思います。「相互相関の前のアップサンプリングは役に立たないのですか?」で説明されています。、相互相関の前に補間またはアップサンプリングしても、実際にはそれ以上の情報は得られません。サブサンプルピークに関する情報は、その周辺のサンプルに含まれています。最小限のエラーで抽出する必要があります。ここにメモを集めました

最も簡単な方法は、二次/放物線補間です。これは、Pythonの例です。それは正確なはずですあなたのスペクトルをガウス窓に基づいている場合、またはピークはサンプル間の中間点に正確に落ちてしまった場合、しかし、そうでない場合は、いくつかのエラーが発生しました。したがって、あなたの場合、おそらくもっと良いものを使いたいでしょう。

これは、より複雑ですがより正確な推定量のリストです。「上記の方法の中で、クインの2番目の推定量はRMSエラーが最小です。」

数学はわかりませんが、この論文では、放物線補間の理論的精度はFFTビンの幅の5%であるとしています。

相互相関出力でFFT補間を使用してもバイアスエラーは発生しないため、本当に高い精度が必要な場合はこれが最適です。精度と計算速度のバランスをとる必要がある場合は、FFT補間を行ってから、他の推定量のいずれかを実行して、「十分な」結果を得ることが推奨されます。

これは放物線近似を使用するだけですが、ノイズが低い場合はオフセットの正しい値を出力します。

def parabolic_polyfit(f, x, n):
    a, b, c = polyfit(arange(x-n//2, x+n//2+1), f[x-n//2:x+n//2+1], 2)
    xv = -0.5 * b/a
    yv = a * xv**2 + b * xv + c

    return (xv, yv)

arraysize = 1001
fluxlevel = 100.0
noise = 0.3 # 2.0 is too noisy for sub-sample accuracy
signal_std = 15.0
signal_depth = 40.0
gaussian = lambda x: np.exp(-(mu-x)**2/ (2 * signal_std))
mu = 500.1
a_flux = np.array([ra.normalvariate(fluxlevel, noise) for x in range(arraysize)] - gaussian(np.arange(arraysize)) * signal_depth)
mu = 500.8
b_flux = np.array([ra.normalvariate(fluxlevel, noise) for x in range(arraysize)] - gaussian(np.arange(arraysize)) * signal_depth)

a_flux -= np.mean(a_flux)
b_flux -= np.mean(b_flux)

corr = ss.fftconvolve(b_flux, a_flux[::-1])

peak = np.argmax(corr)
px, py = parabolic_polyfit(corr, peak, 13)

px = px - (len(a_flux) - 1)
print px

ここに画像の説明を入力してください ここに画像の説明を入力してください

サンプルのノイズにより、サンプル全体よりも結果が異なるため、それを減らしました。ピークのより多くのポイントを使用して曲線を当てはめることは、推定をいくらか厳しくするのに役立ちますが、それが統計的に有効であるかどうかはわかりません。

ノイズ= 0.2および3ポイントフィットの場合、オフセット= 0.4に対して0.398および0.402のような値が得られます。

ノイズ= 2.0および13ポイントフィットでは、オフセット= 0.4に対して0.156および0.595のような値が得られます。


この画像の正確な登録問題を解決しようとしています。サブピクセル精度が必要です(0.1で十分でしょう)が、最も重要なのはバイアスが必要ないため、補間方法が機能しません。これには良い(そしてPythonで実装された)メソッドはありますか?ゼロパディングの方法は機能しますが、費用がかかりすぎて実用的ではありません。
keflavich 2012

@kelavich:すべての補間方法をテストして、許容できないバイアスを見つけましたか?推奨されるアプローチは、いくつかのゼロパディングとその後の低エラー補間の組み合わせです。他の方法は知りませんが、これで十分な精度が得られると思います。
内部石

はい、線形および2次補間に許容できないバイアスが見つかりました。私はFFTゼロパディングを試しましたが、結果は高周波リンギングに支配されています...ゼロパディングの例を追加できる可能性はありますか?
keflavich 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.