強度プロファイルのすべての最大値と最小値の位置をDMで見つけることができるかどうかを質問したいと思います。ラインプロファイルからピークを特定する
以下の例でピークの位置を特定する簡単なスクリプトを作成するにはどうすればよいですか?ここ
は、Y方向に沿ったSTEM像の線強度プロファイルのスクリーンショットです:
強度プロファイルのすべての最大値と最小値の位置をDMで見つけることができるかどうかを質問したいと思います。ラインプロファイルからピークを特定する
以下の例でピークの位置を特定する簡単なスクリプトを作成するにはどうすればよいですか?ここ
は、Y方向に沿ったSTEM像の線強度プロファイルのスクリーンショットです:
最も簡単な方法かどうか、を決定する1点(または2点)近傍を使用することです中心は最小(最大)です。最大条件は> =ここで
if (y(x) > y(x-1) and y(x-1) >= y(x-2) and y(x) > y(x+1) and y(x+1) >= y(x+2))
注かもしれない2点近隣
// assume 0 <= x <= maxX, y(x) is value at point x, radius is 1
x = 1;
while (x + 1 <= maxX)
{
if (y(x) > y(x-1) and y(x) > y(x+1))
// we found a maximum at x
if (y(x) < y(x-1) and y(x) < y(x+1))
// we found a minimum at x
x = x + 1
}
:以下の擬似コードを参照してください。 >を代わりに使用できます。
2つの連続したxが同じ値yを持つ場合、上記の方法では最大値が見つからないことに注意してください。 y = 0、y(1)= 1、y(2)= 1、y(3)= 0の場合、x = 1でもx = 2でも最大値を見つけることができない。
"厳密な"ローカルマキシマをフィルタリングしたい場合は、イメージ式と条件付き "tert"演算子で簡単に行うことができます。次の例は、この説明:
image CreateTestSpec(number nChannels, number nPeaks, number amp, number back)
{
image testImg := RealImage("TestSpec", 4, nChannels)
testImg = amp * cos(PI() + 2*PI() * nPeaks * icol/(iwidth-1))
testImg += back
testImg = PoissonRandom(testImg)
return testImg
}
image FilterLocalMaxima1D(image spectrumIn, number range)
{
image spectrumOut := spectrumIn.ImageClone()
for(number dx = -range; dx<=range; dx++ )
spectrumout *= (spectrumIn >= offset(spectrumIn,dx,0) ? 1 : 0)
spectrumout.SetName("Local maxima ("+range+") filtered")
return spectrumOut
}
image test1 := CreateTestSpec(256,10,1000,5000)
image test2 := FilterLocalMaxima1D(test1,3)
test1.ShowImage()
test2.ShowImage()
をしかし、(また、あなたの例のイメージで)ノイズを考慮すると、あなたが本当に欲しいものを取得していることを確認するには、これらの「極大値」の周りにフィットを実行したい場合があります。上からのデータはそれの出発点にすぎません。
また、各ピークで実際のデータフィッティングを行う代わりに、データを平均化してからローカル極大値を求めることができます。これは特に、実際の山の幅をかなりよく知っている場合に効果的です。
これは、例えば次のようになります。
image CreateTestSpec(number nChannels, number nPeaks, number amp, number back)
{
image testImg := RealImage("TestSpec", 4, nChannels)
testImg = amp * cos(PI() + 2*PI() * nPeaks * icol/(iwidth-1))
testImg += back
testImg = PoissonRandom(testImg)
return testImg
}
image FilterLocalMaxima1D(image spectrumIn, number range)
{
image spectrumOut := spectrumIn.ImageClone()
for(number dx = -range; dx<=range; dx++ )
spectrumout *= (spectrumIn >= offset(spectrumIn,dx,0) ? 1 : 0)
spectrumout.SetName("Local maxima ("+range+") filtered")
return spectrumOut
}
image FilterLocalMaxima1DAveraged(image spectrumIn, number range)
{
image avSpectrum := spectrumIn.ImageClone()
avSpectrum = 0
for(number dx = -range; dx<=range; dx++ )
avSpectrum += offset(spectrumIn,dx,0)
avSpectrum *= 1/(2*range+1)
image spectrumOut := spectrumIn.ImageClone()
for(number dx = -range; dx<=range; dx++ )
spectrumout *= (avSpectrum >= offset(avSpectrum,dx,0) ? 1 : 0)
spectrumout.SetName("Local maxima ("+range+") filtered, average")
return spectrumOut
}
image test1 := CreateTestSpec(256,10,1000,5000)
image maxPeaks := FilterLocalMaxima1D(test1,3)
image maxPeaksAv := FilterLocalMaxima1DAveraged(test1,3)
test1.ShowImage()
test1.ImageGetImageDisplay(0).ImageDisplayAddImage(maxPeaks, "local max")
test1.ImageGetImageDisplay(0).ImageDisplayAddImage(maxPeaksAv, "local max from Average")
test1.ImageGetImageDisplay(0).LinePlotImageDisplaySetSliceComponentColor(0, 1, 0.7, 0.7, 0.7)
test1.ImageGetImageDisplay(0).LinePlotImageDisplaySetSliceDrawingStyle(1, 2)
test1.ImageGetImageDisplay(0).LinePlotImageDisplaySetSliceComponentColor(1, 1, 1, 0, 0)
test1.ImageGetImageDisplay(0).LinePlotImageDisplaySetSliceTransparency(1, 1, 0.7)
test1.ImageGetImageDisplay(0).LinePlotImageDisplaySetSliceDrawingStyle(2, 2)
test1.ImageGetImageDisplay(0).LinePlotImageDisplaySetSliceComponentColor(2, 1, 0, 1, 0)
test1.ImageGetImageDisplay(0).LinePlotImageDisplaySetSliceTransparency(2, 1, 0.7)