2015年11月2日

imagej用Macro邊緣偵測後測量多層厚度

這是延續上次的imagej用Macro測多層厚度

因為提問的人說了

不好意思 我另外還有一個更深入的問題
想要跟您請教一下
是有關 [Edge Detection,邊界偵測]的
請參考我的附件
一般我們做出的灰階圖屬於一次微分
ImageJ有辦法得到二次微分的數據嗎

會有這個問題其實是您的影片中
設定區別不同層的灰階值數值時(我目前都是取半高寬)
但是換一個人來取這個值
直接就會影響到最後的膜厚
這樣會有誤差

目前我想到的方法是搭配二次微分的影像或數據來處理
能得到誤差較小的結果
不知道您的看法呢
或是您有更好的辦法去定義邊界
請再不吝賜教好嗎?」

附上這份文件的第五頁、第六頁

灰階的突然變化(Abrupt Change)即是測邊的主要觀念之一。 „ 一次微分後形成的波峰(Peak),正代表著兩個區域的邊緣處。 若波峰夠高,也就是已超過門檻值(Threshold),已足以說明在 該處有邊點形成的邊線(Edge Line)。


有資料之後,我想了想,其實imagej就有邊緣偵測的功能
是在Process/Find Edges
我只要事先用這個功能去取得灰階突然變化值就行了
於是把先前的code改一改,這樣就可以直接測出各層厚度了,也不會因為不同人取用不同門檻值而造成誤差。
===========code========================================
macro "Measure Multilayers2" {
   

   run("Duplicate...", " ");
   run("Select All");
   run("Find Edges");


    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=1; i<profile.length-1; i++){

        if(profile[i-1]<profile[i] && profile[i]>profile[i+1]&&profile[i]>150   ) {
        x1[j]=i;
        j++;
       }

        if(profile[i-1]<profile[i] && profile[i]==profile[i+1]&&profile[i]>200  ) {
        x1[j]=i;
        j++;
       }

    }

//    for(i=0;i<profile.length;i++)     print(x1[i]);

    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();
}