基于ImageJ的粒子光斑检视器

问题

在对粒子进行分类过滤的时候

常常会出现一些假阳性或者假阴性的情况

为了提高粒子过滤的准确性

就希望能够针对一些程序自动判断出错的少数个例

进行参数的优化调整

我们希望实现的功能是

点击图像上某个粒子光斑

程序会输出这个粒子光斑的截图

以及粒子分类结果和粒子对应参数

代码
//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色度饱和度强度参数

而且还会有对应的参数


猜你喜欢

转载自blog.csdn.net/sheldonxxd/article/details/80951822