问题
I would like to measure the percentage of purple area of this gray map.
I can say roughly speaking that represents the 10% of the area, but I need an exact value.
I know there is a free tool called ImageJ but I don't know how to use it.
Maybe you can suggest me another tool or how to perform such task.
Thanks in advance.
回答1:
You could write a small ImageJ plugin for that task:
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
}
}
This plugin will open the following dialog:
This dialog allows to set both the pixel of interest (POI) color as well as the background (bckg) color.Via setting the distances manually, one can decide what the plugin determines as POI or as background. The reference colors are as following:
POI:
Background:
To verify you are using the right distance settings, i recommend to use the preview function. While using that, ImageJ will color every pixel it considers as POI red, whilst every background pixel will be colored black. I got the following result using the settings given in the dialog:
As you can see, due to the artifacting some of the white pixels are also considered as background. Also the text is considered as background, so i recommend to remove it before using the plugin. If get rid of it, the result slightly changes to around 4.2%.
来源:https://stackoverflow.com/questions/50826680/how-to-measure-percentages-of-colored-areas-over-background-imagej