问题
在对粒子进行分类过滤的时候
常常会出现一些假阳性或者假阴性的情况
为了提高粒子过滤的准确性
就希望能够针对一些程序自动判断出错的少数个例
进行参数的优化调整
我们希望实现的功能是
点击图像上某个粒子光斑
程序会输出这个粒子光斑的截图
以及粒子分类结果和粒子对应参数
代码
//particle picker 手动版本,单击图像中某个粒子,即可显示其类别和基本信息
//截图区域半径为8,先获取粒子光斑截图
size = 8;
leftButton = 16;
flags = 0;
ID = getTitle();
while(flags&leftButton == 0) getCursorLoc(x,y,z,flags);
showMessage("Mark Particle Center:"+x+","+y);
makeRectangle(x-size,y-size,2*size+1,2*size+1);
run("Duplicate...","title=particle");
//--------------
function pcheck(x,y){
s = 17;
n = (s-1)/2;
bri = newArray(n);
makeRectangle(x-n-1,y-n-1,s,s);
getStatistics(area, mean, min, max, std, histogram);
if (mean<60){
setMinAndMax(min,max);
} // 为弱信号准备的
for(i=0;i<n;i++){
makeRectangle(x-n-1+i,y-n-1+i,s-2*i,s-2*i);
getStatistics(area, mean, min, max, std, histogram);
bri[i] = mean;
}
k = newArray(4);
for(i=0;i<4;i++){
k[i] = bri[i+4]-bri[i+3];
}
Array.getStatistics(k,min,max,mean,sd);
if (mean>20) return true;
else return false;
}
if (pcheck(9,9)){
showMessage("is particle!");
}
else showMessage("not particle!");
//global parameters------
hue_blue = 280;
hue_green = 160;
hue_yellow = 65;
p_noise = 20;
//Partile filter------
function getRGB(x,y){
RGB = newArray(3);
v = getPixel(x,y);
RGB[0] = (v>>16)&0xff;
RGB[1] = (v>>8)&0xff;
RGB[2] = v&0xff;
return RGB;
}
function RGB2HSI(RGB){
RGB[0] = RGB[0]/255;
RGB[1] = RGB[1]/255;
RGB[2] = RGB[2]/255;
Array.getStatistics(RGB,min,max);
R = RGB[0];
G = RGB[1];
B = RGB[2];
I = (R+G+B)/3;
n = (R-G)+(R-B)+(1e-6);
m = (R-G)*(R-G)+(R-B)*(G-B);
m = 2*sqrt(m)+(1e-6);
sigma = acos(n/m);
if (G>=B) H = sigma;
else H = 2*PI-H;
S = 1 - 3*min/(R+G+B);
HSI = newArray(3);
HSI[0] = H*180/PI;
HSI[1] = S;
HSI[2] = I*255;
return HSI;
}
function getHSI(x,y){
RGB = getRGB(x,y);
HSI = RGB2HSI(RGB);
return HSI;
}
function collectpixels(x,y){
s = 5;
makeRectangle(x,y,s,s);
pixels = newArray(s*s);
for(i=0;i<s;i++){
for(j=0;j<s;j++){
pixels[s*i+j]=getPixel(x+i,y+j);
}
}
return pixels;
}
function pHSI(pixels){ //依赖于RGB2HSI
n = lengthOf(pixels);
HueSum = 0;
Hue_n = 0;
SatSum = 0;
Sat_n = 0;
BriSum = 0;
Bri_n = 0;
for(i=0;i<n;i++){
RGB = newArray(3);
v = pixels[i];
RGB[0] = (v>>16)&0xff;
RGB[1] = (v>>8)&0xff;
RGB[2] = v&0xff;
HSI = RGB2HSI(RGB);
if (HSI[2]>60){
if (HSI[1]>0.2){
HueSum = HueSum + HSI[0];
Hue_n = Hue_n + 1;
SatSum = SatSum + HSI[1];
Sat_n = Sat_n + 1;
BriSum = BriSum + HSI[2];
Bri_n = Bri_n + 1;
}
}
}
hsi = newArray(HueSum/Hue_n,SatSum/Sat_n,BriSum/Bri_n);
return hsi;
}
function pfilter(x,y,show){ //依赖于collectpixels和pHSI
pixels = collectpixels(x,y);
hsi = pHSI(pixels);
if (show) {
print("###particle HSI###");
Array.print(newArray("hue","saturation","intensity"));
Array.print(hsi);
}
if (hsi[0]>hue_blue && hsi[2]>0.2){
type = 1;
}
else if (hsi[0]<hue_green && hsi[0]>hue_yellow){
type = 2;
}
else if (hsi[0]<=hue_yellow){
type = 3;
}
else {
type = 0;
}
return type;
}
ptype = pfilter(9,9,true);
if (ptype==0) showMessage("is noise!");
if (ptype==1) showMessage("is monomer!");
if (ptype==2) showMessage("is dimer!");
if (ptype==3) showMessage("is polymer!");
步骤
先运行macro脚本,然后在图像上点击某个粒子光斑
程序会反馈你选择的位置
点击OK之后,程序先会检查这是否是一个光斑
单击OK之后,再判断光斑的类别(绿色的是AgNP dimer),并输出其有效HSI色度饱和度强度参数
而且还会有对应的参数