|
StackStatistics |
|
package ij.process;
import ij.*;
import ij.gui.*;
import ij.measure.*;
import ij.plugin.filter.Analyzer;
import java.awt.*;
/** Statistics, including the histogram, of a stack. */
public class StackStatistics extends ImageStatistics {
public StackStatistics(ImagePlus imp) {
doCalculations(imp, 256, 0.0, 0.0);
}
public StackStatistics(ImagePlus imp, int nBins, double histMin, double histMax) {
doCalculations(imp, nBins, histMin, histMax);
}
void doCalculations(ImagePlus imp, int bins, double histogramMin, double histogramMax) {
ImageProcessor ip = imp.getProcessor();
boolean limitToThreshold = (Analyzer.getMeasurements()&LIMIT)!=0;
double minThreshold = -Float.MAX_VALUE;
double maxThreshold = Float.MAX_VALUE;
Calibration cal = imp.getCalibration();
if (limitToThreshold && ip.getMinThreshold()!=ImageProcessor.NO_THRESHOLD) {
minThreshold=cal.getCValue(ip.getMinThreshold());
maxThreshold=cal.getCValue(ip.getMaxThreshold());
}
nBins = bins;
histMin = histogramMin;
histMax = histogramMax;
ImageStack stack = imp.getStack();
int size = stack.getSize();
ip.setRoi(imp.getRoi());
byte[] mask = ip.getMaskArray();
float[] cTable = imp.getCalibration().getCTable();
histogram = new int[nBins];
double v;
double sum = 0;
double sum2 = 0;
int width, height;
int rx, ry, rw, rh;
double pw, ph;
width = ip.getWidth();
height = ip.getHeight();
Rectangle roi = ip.getRoi();
if (roi != null) {
rx = roi.x;
ry = roi.y;
rw = roi.width;
rh = roi.height;
} else {
rx = 0;
ry = 0;
rw = width;
rh = height;
}
pw = 1.0;
ph = 1.0;
roiX = rx*pw;
roiY = ry*ph;
roiWidth = rw*pw;
roiHeight = rh*ph;
boolean fixedRange = histMin!=0 || histMax!=0.0;
// calculate min and max
double roiMin = Double.MAX_VALUE;
double roiMax = -Double.MAX_VALUE;
for (int slice=1; slice<=size; slice++) {
IJ.showStatus("Calculating stack histogram...");
IJ.showProgress(slice/2, size);
ip = stack.getProcessor(slice);
ip.setCalibrationTable(cTable);
for (int y=ry, my=0; y<(ry+rh); y++, my++) {
int i = y * width + rx;
int mi = my * rw;
for (int x=rx; x<(rx+rw); x++) {
if (mask==null || mask[mi++]!=0) {
v = ip.getPixelValue(x,y);
if (v>=minThreshold && v<=maxThreshold) {
if (v<roiMin) roiMin = v;
if (v>roiMax) roiMax = v;
}
}
i++;
}
}
}
min = roiMin;
max = roiMax;
if (fixedRange) {
if (min<histMin) min = histMin;
if (max>histMax) max = histMax;
} else {
histMin = min;
histMax = max;
}
// Generate histogram
double scale = nBins/( histMax-histMin);
pixelCount = 0;
int index;
boolean first = true;
for (int slice=1; slice<=size; slice++) {
IJ.showProgress(size/2+slice/2, size);
ip = stack.getProcessor(slice);
ip.setCalibrationTable(cTable);
for (int y=ry, my=0; y<(ry+rh); y++, my++) {
int i = y * width + rx;
int mi = my * rw;
for (int x=rx; x<(rx+rw); x++) {
if (mask==null || mask[mi++]!=0) {
v = ip.getPixelValue(x,y);
if (v>=minThreshold && v<=maxThreshold && v>=histMin && v<=histMax) {
pixelCount++;
sum += v;
sum2 += v*v;
index = (int)(scale*(v-histMin));
if (index>=nBins)
index = nBins-1;
histogram[index]++;
}
}
i++;
}
}
}
area = pixelCount*pw*ph;
mean = sum/pixelCount;
calculateStdDev(pixelCount, sum, sum2);
histMin = cal.getRawValue(histMin);
histMax = cal.getRawValue(histMax);
binSize = (histMax-histMin)/nBins;
dmode = getMode(cal);
IJ.showStatus("");
IJ.showProgress(1.0);
}
double getMode(Calibration cal) {
int count;
maxCount = 0;
for (int i = 0; i < nBins; i++) {
count = histogram[i];
if (count > maxCount) {
maxCount = count;
mode = i;
}
}
return cal.getCValue(histMin+mode*binSize);
}
}
|
StackStatistics |
|