Imagej要測量一個顆粒的最大徑最小徑,用其內建功能就行
請看此篇
用Imagej測最大粒徑和最小粒徑
不過測量最大徑最小徑,還有一種叫做Rotating calipers。上面的連結中,本來有個外掛就是用那個演算法在測最大徑最小徑的,不過後來外掛死掉了。
Rotating Caliper又叫做旋轉卡殼,想像有個兩條平行的尺夾住你要測量的多邊形,一邊夾一邊旋轉。(可以看看這篇連結文章,寫得很清楚)
计算几何之凸包(三) {旋转卡壳初步
前幾天為了作最小徑,又不想用Feret的方法,所以就嘗試用了Rotating Caliper的演算法來測量顆粒的長徑和短徑,是用Imagej的Macro寫成的。把底下的程式複製之後貼到Imagej的Plugin/New/Macro,然後去Run就行了。
執行前要先把選取區都加入ROI裡頭,這個Macro就是去處理每個ROI裡的多邊形選取區,去計算利用Rotating Caliper夾出來的最大徑和最小徑。這個會和Feret的徑會不一樣長,因為是不同的夾法。
在Result視窗或是Log視窗出現的MinCaliper和MaxCaliper就是測量的結果。
=========================
vResult=getValue("results.count");
IJ.deleteRows(0,vResult);
//count how many selection in ROI Manager
n = roiManager("count");
for (i=0; i<n; i++) {
roiManager("select", i);
run("Convex Hull");
roiManager("Update");
getStatistics(area, mean);
setResult("Area", i, area);
setResult("Mean", i, mean);
//measure each selection area
getSelectionCoordinates(x, y);
//how many points in the polygon >>m
m =x.length;
lengthArray=newArray(m);
for (j=0; j<m; j++){
// print(i);
area = 0;
//how many triangle in the polygon>>m-2
areaArray=newArray(m-1);
for (k=1; k<m;k++){
p0=j%m;
p1=(j+1)%m;
p2=(j+1+k)%m;
lengthBottom=sqrt(pow((x[p0]-x[p1]),2)+pow((y[p0]-y[p1]),2));
// print(p0+" "+p1+" "+p2);
area += x[p0]*y[p1] - x[p1]*y[p0];
area += x[p1]*y[p2] - x[p2]*y[p1];
area += x[p2]*y[p0] - x[p0]*y[p2];
area /= 2;
if (area<0) area = -area;
//print(i+" "+p0+" "+p1+" "+p2+" "+area);
//print(area);
areaArray[k-1]=area;
if(k>1){
if(areaArray[k-1]<areaArray[k-2]) {
//print(areaArray[k-2]); //Maximan Area
height=areaArray[k-2]*2/lengthBottom;
//print(height);
break;
}
}
}
lengthArray[j]=height;
}
MinCaliper=Array.findMinima(lengthArray,1);
MaxCaliper=Array.findMaxima(lengthArray,1);
print("MinCaliper:"+lengthArray[MinCaliper[0]]);
print("MaxCaliper:"+lengthArray[MaxCaliper[0]]);
setResult("MinCaliper", i, lengthArray[MinCaliper[0]]);
setResult("MaxCaliper", i, lengthArray[MaxCaliper[0]]);
}