2017-01-18 90 views
0

我想問一下,是否有可能找到強度輪廓的每個最大值和最小值在DM上的位置。從線輪廓識別峯

我如何想出一個簡單的腳本來標識下面例子中峯的位置?

下面是沿Y方向的STEM圖像的線強度分佈的屏幕截圖:

Screenshot of line intensity profile of a STEM image along the Y-direction

回答

0

最簡單的方法是使用1點(或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點附近最大條件可能是

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)) 

注> =這裏。你可以用>代替。

請注意,如果兩個連續的x具有相同的值y,則以上方法將不會找到最大值,例如,對於y(0)= 0,y(1)= 1,y(2)= 1,y(3)= 0,對於x = 1也不會找到最大值,對於x = 2也不會達到最大值。

1

如果要篩選「嚴格」局部最大值,則可以使用圖像表達式和條件「叔」運算符輕鬆完成此操作。下面的例子說明了這一點:

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)