有網友寫信來問imagej的問題「怎麼測多層膜的厚度」
哎呦!那還不簡單,就一條一條畫線,然後用Analyze/Measure不就好了。如果有一百層,那就作一百次就好了啊。
如果真的這樣作,應該會死人吧?那怎麼作哩?
那就要靠coding了,imagej有提供Macros(巨集)的功能,線上也有詳細的說明書,另外還有幾百個範例檔。於是我研究了一下,寫一個簡單的程式就搞定了。
方法是這樣
先設定好你要的臨界灰階值是多少?意思就是用灰階值去區分你的不同層材料,比方說灰階值100以上就叫做A層,100以下叫做B層。那接下來就是用profile的功能去畫出x軸和灰階值的折線圖,然後去找出來這個折線圖和臨界灰階那條橫線的交會點。找到數個交會點之後,把x座標減一減,就可以得到各層的厚度了。
好的,我打賭應該看不懂我寫什麼,沒關係,反正那是寫給我看的。
底下有錄製一段影片,有需求的就自己看看,然後程式碼擺在本文章最底下,複製貼上自己改就行了。
macro "Measure Multilayers" {
Dialog.create("Set Threshold");
Dialog.addNumber("threshold:", 100);
Dialog.show();
thre = Dialog.getNumber();
run("Clear Results");
print("\\Clear")
profile = getProfile();
getPixelSize(scale, pixelSize, trash);
xAxis=newArray(profile.length)
x1=newArray(profile.length);
var j=0;
for (i=0; i<profile.length; i++)
xAxis[i]=i*pixelSize;
for (i=0; i<profile.length-1; i++){
if(profile[i]<thre && profile[i+1]>thre) {
x1[j]=i;
j++;
}
if(profile[i]>thre && profile[i+1]<thre) {
x1[j]=i;
j++;
}
}
k=0;
while(x1[k+1]!=0){
print(k+1,"\t",(x1[k+1]-x1[k])*pixelSize,scale);
k++;
}
Plot.create("profile","Distance "+ scale, "Grey Value", xAxis,profile);
Plot.show();
}