如何测量背景上彩色区域的百分比?图片J?
How to measure percentages of colored areas over background? ImageJ?
我想测量这张灰色地图的紫色区域百分比。
我可以粗略地说代表10%的面积,但我需要一个确切的值。
我知道有一个名为 ImageJ 的免费工具,但我不知道如何使用它。
也许你可以建议我使用其他工具或如何执行此类任务。
提前致谢。
您可以为该任务编写一个小的 ImageJ 插件:
import ij.gui.DialogListener;
import ij.gui.GenericDialog;
import ij.plugin.filter.ExtendedPlugInFilter;
import ij.plugin.filter.PlugInFilterRunner;
import ij.process.ImageProcessor;
import ij.IJ;
import ij.ImagePlus;
import java.awt.AWTEvent;
import java.awt.Label;
import java.lang.Math;
public class Purple_Counter implements ExtendedPlugInFilter, DialogListener{
private final int FLAGS = DOES_RGB | PARALLELIZE_STACKS;
private boolean preview = true;
private ImagePlus im;
private int count;
private double total;
private int color = 0xff64318a;
private int background = 0xffd7d7d7;
private double maxDistanceColor;
private double maxDistanceBckg ;
public int setup(String args, ImagePlus im){
this.im = im;
maxDistanceColor = 60;
maxDistanceBckg = 60;
return FLAGS;
}
public void run(ImageProcessor ip){
int height = ip.getHeight();
int width = ip.getWidth();
count = 0;
total = 0;
for(int a = 0; a < height; a++){
for(int b = 0; b < height; b++){
int p = ip.getPixel(a,b);
if ( calculateDistance(p,color) < maxDistanceColor){
count++;
ip.putPixel(a,b,0xffff0000);
}
if ( calculateDistance(p,background) < maxDistanceBckg){
total++;
ip.putPixel(a,b,0xff000000);
}
}
}
IJ.log("Counted: " + count + "| Total: " + total);
IJ.log("Percentage: " + (count/total) * 100f);
IJ.log("");
}
private double calculateDistance(int color1, int color2){
int red1 = (color1 >> 16)&0xff;
int red2 = (color2 >> 16)&0xff;
int green1 = (color1 >> 8)&0xff;
int green2 = (color2 >> 8)&0xff;
int blue1 = color1 & 0xff;
int blue2 = color2 & 0xff;
double distance = Math.sqrt((red1 * red1 - 2*red1*red2 + red2*red2) + (green1 * green1 - 2*green1*green2 + green2*green2) + (blue1 * blue1 - 2*blue1*blue2 + blue2*blue2));
return distance;
}
public int showDialog(ImagePlus imp, String Command, PlugInFilterRunner pfr){
//Dialog to control the used color distances
GenericDialog gd = new GenericDialog("Distance Settings");
gd.addMessage("Please chose maximal distances to identify POI and background pixels: ");
gd.addSlider("POI Red: ", 0,255,0x64);
gd.addSlider("POI Green: ", 0,255,0x31);
gd.addSlider("POI Blue: ", 0,255,0x8a);
gd.addSlider("BCKG Red: ", 0,255,0xd7);
gd.addSlider("BCKG Green: ", 0,255,0xd7);
gd.addSlider("BCKG Blue: ", 0,255,0xd7);
gd.addSlider("POI max. Distance: ", 0.001, 1000, maxDistanceColor);
gd.addSlider("BCKG max. Distance: ", 0.001, 1000, maxDistanceBckg);
gd.addPreviewCheckbox(pfr, "Preview");
gd.addDialogListener(this);
gd.showDialog();
if(gd.wasCanceled() ||!dialogItemChanged(gd, null)){
return DONE;
}
return IJ.setupDialog(imp, FLAGS);
}
public boolean dialogItemChanged(GenericDialog gd, AWTEvent e){
int alpha = 0xff;
int colorRed = (int)gd.getNextNumber();
int colorGreen = (int)gd.getNextNumber();
int colorBlue = (int)gd.getNextNumber();
int bckgRed = (int)gd.getNextNumber();
int bckgGreen = (int)gd.getNextNumber();
int bckgBlue = (int)gd.getNextNumber();
color = (alpha << 24 | colorRed << 16 | colorGreen << 8 | colorBlue);
background = (alpha << 24 | bckgRed << 16 | bckgGreen << 8 | bckgBlue);
maxDistanceColor = gd.getNextNumber();
maxDistanceBckg = gd.getNextNumber();
return true;
}
public void setNPasses(int nPasses){
//Has to be implemented for ExtendedPlugInFilter
}
}
此插件将打开以下对话框:
此对话框允许设置感兴趣像素 (POI) 颜色和背景 (bckg) color.Via 手动设置距离,可以决定插件将什么确定为 POI 或背景。
参考颜色如下:
兴趣点:
背景:
为了验证您使用的距离设置是否正确,我建议使用预览功能。在使用它时,ImageJ 会将它认为是 POI 的每个像素着色为红色,而每个背景像素都将着色为黑色。我使用对话框中给出的设置得到以下结果:
如您所见,由于伪影,一些白色像素也被视为背景。文本也被视为背景,所以我建议在使用插件之前将其删除。如果去掉它,结果会稍微变化到 4.2% 左右。
我想测量这张灰色地图的紫色区域百分比。
我可以粗略地说代表10%的面积,但我需要一个确切的值。
我知道有一个名为 ImageJ 的免费工具,但我不知道如何使用它。
也许你可以建议我使用其他工具或如何执行此类任务。
提前致谢。
您可以为该任务编写一个小的 ImageJ 插件:
import ij.gui.DialogListener;
import ij.gui.GenericDialog;
import ij.plugin.filter.ExtendedPlugInFilter;
import ij.plugin.filter.PlugInFilterRunner;
import ij.process.ImageProcessor;
import ij.IJ;
import ij.ImagePlus;
import java.awt.AWTEvent;
import java.awt.Label;
import java.lang.Math;
public class Purple_Counter implements ExtendedPlugInFilter, DialogListener{
private final int FLAGS = DOES_RGB | PARALLELIZE_STACKS;
private boolean preview = true;
private ImagePlus im;
private int count;
private double total;
private int color = 0xff64318a;
private int background = 0xffd7d7d7;
private double maxDistanceColor;
private double maxDistanceBckg ;
public int setup(String args, ImagePlus im){
this.im = im;
maxDistanceColor = 60;
maxDistanceBckg = 60;
return FLAGS;
}
public void run(ImageProcessor ip){
int height = ip.getHeight();
int width = ip.getWidth();
count = 0;
total = 0;
for(int a = 0; a < height; a++){
for(int b = 0; b < height; b++){
int p = ip.getPixel(a,b);
if ( calculateDistance(p,color) < maxDistanceColor){
count++;
ip.putPixel(a,b,0xffff0000);
}
if ( calculateDistance(p,background) < maxDistanceBckg){
total++;
ip.putPixel(a,b,0xff000000);
}
}
}
IJ.log("Counted: " + count + "| Total: " + total);
IJ.log("Percentage: " + (count/total) * 100f);
IJ.log("");
}
private double calculateDistance(int color1, int color2){
int red1 = (color1 >> 16)&0xff;
int red2 = (color2 >> 16)&0xff;
int green1 = (color1 >> 8)&0xff;
int green2 = (color2 >> 8)&0xff;
int blue1 = color1 & 0xff;
int blue2 = color2 & 0xff;
double distance = Math.sqrt((red1 * red1 - 2*red1*red2 + red2*red2) + (green1 * green1 - 2*green1*green2 + green2*green2) + (blue1 * blue1 - 2*blue1*blue2 + blue2*blue2));
return distance;
}
public int showDialog(ImagePlus imp, String Command, PlugInFilterRunner pfr){
//Dialog to control the used color distances
GenericDialog gd = new GenericDialog("Distance Settings");
gd.addMessage("Please chose maximal distances to identify POI and background pixels: ");
gd.addSlider("POI Red: ", 0,255,0x64);
gd.addSlider("POI Green: ", 0,255,0x31);
gd.addSlider("POI Blue: ", 0,255,0x8a);
gd.addSlider("BCKG Red: ", 0,255,0xd7);
gd.addSlider("BCKG Green: ", 0,255,0xd7);
gd.addSlider("BCKG Blue: ", 0,255,0xd7);
gd.addSlider("POI max. Distance: ", 0.001, 1000, maxDistanceColor);
gd.addSlider("BCKG max. Distance: ", 0.001, 1000, maxDistanceBckg);
gd.addPreviewCheckbox(pfr, "Preview");
gd.addDialogListener(this);
gd.showDialog();
if(gd.wasCanceled() ||!dialogItemChanged(gd, null)){
return DONE;
}
return IJ.setupDialog(imp, FLAGS);
}
public boolean dialogItemChanged(GenericDialog gd, AWTEvent e){
int alpha = 0xff;
int colorRed = (int)gd.getNextNumber();
int colorGreen = (int)gd.getNextNumber();
int colorBlue = (int)gd.getNextNumber();
int bckgRed = (int)gd.getNextNumber();
int bckgGreen = (int)gd.getNextNumber();
int bckgBlue = (int)gd.getNextNumber();
color = (alpha << 24 | colorRed << 16 | colorGreen << 8 | colorBlue);
background = (alpha << 24 | bckgRed << 16 | bckgGreen << 8 | bckgBlue);
maxDistanceColor = gd.getNextNumber();
maxDistanceBckg = gd.getNextNumber();
return true;
}
public void setNPasses(int nPasses){
//Has to be implemented for ExtendedPlugInFilter
}
}
此插件将打开以下对话框:
此对话框允许设置感兴趣像素 (POI) 颜色和背景 (bckg) color.Via 手动设置距离,可以决定插件将什么确定为 POI 或背景。 参考颜色如下:
兴趣点:
背景:
为了验证您使用的距离设置是否正确,我建议使用预览功能。在使用它时,ImageJ 会将它认为是 POI 的每个像素着色为红色,而每个背景像素都将着色为黑色。我使用对话框中给出的设置得到以下结果:
如您所见,由于伪影,一些白色像素也被视为背景。文本也被视为背景,所以我建议在使用插件之前将其删除。如果去掉它,结果会稍微变化到 4.2% 左右。