use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.
the class ImageBackground method run.
/*
* (non-Javadoc)
*
* @see ij.plugin.filter.PlugInFilter#run(ij.process.ImageProcessor)
*/
public void run(ImageProcessor ip) {
ImageProcessor median = getProjection();
//Utils.display("Median", median);
ImageProcessor background = applyBlur(median);
subtractBias(background);
Utils.display("Background", background);
// Q. Is there a better way to do the thresholding for foreground pixels.
// Ideally we want to outline cell shapes.
ImageProcessor mask = median.convertToByte(true);
mask.autoThreshold();
Utils.display("Mask", mask);
}
use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.
the class ImageBackground method getProjection.
private ImageProcessor getProjection() {
// Get median intensity projection
ZProjector p = new ZProjector(imp);
p.setMethod(ZProjector.MEDIAN_METHOD);
p.doProjection();
ImageProcessor median = p.getProjection().getProcessor();
return median;
}
use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.
the class BinaryDisplay method setup.
/* (non-Javadoc)
* @see ij.plugin.filter.PlugInFilter#setup(java.lang.String, ij.ImagePlus)
*/
public int setup(String arg, ImagePlus imp) {
SMLMUsageTracker.recordPlugin(this.getClass(), arg);
if (imp == null)
return DONE;
if (arg.equals("reset")) {
ImageProcessor ip = imp.getProcessor();
ip.reset();
imp.setProcessor(ip);
imp.resetDisplayRange();
imp.updateAndDraw();
return DONE;
}
this.imp = imp;
return DOES_ALL;
}
use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.
the class PCPALMAnalysis method analyse.
/**
* Perform the PC Analysis
*
* @param molecules
*/
private void analyse(ArrayList<Molecule> molecules) {
// Check if the plots are currently shown
String spatialPlotTitle = TITLE + " molecules/um^2";
String frequencyDomainTitle = TITLE + " g(r)";
boolean noPlots;
String topPlotTitle;
long start = System.nanoTime();
if (spatialDomain) {
// -----------------
// Analysis in the spatial domain
// -----------------
log("---");
log("Spatial domain analysis");
log("Computing density histogram");
// Compute all-vs-all distance matrix.
// Create histogram of distances at different radii.
final int nBins = (int) (correlationDistance / correlationInterval) + 1;
final double maxDistance2 = correlationDistance * correlationDistance;
int[] H = new int[nBins];
// TODO - Update this using a grid with a resolution of maxDistance to increase speed
// by only comparing to neighbours within range.
// An all-vs-all analysis does not account for a border.
// A simple solution is to only process molecules within the border but compare them
// to all molecules within the region. Thus every molecule has a complete circle of the max
// radius around them to use:
// ----------------------
// | |
// | -------------- |
// | | Within | |
// | | Border | |
// | | | |
// | -------------- |
// | Region |
// ----------------------
// If the fraction of points within the correlation distance of the edge is low then this
// will not make much difference.
final double boundaryMinx = (useBorder) ? minx + correlationDistance : minx;
final double boundaryMaxx = (useBorder) ? maxx - correlationDistance : maxx;
final double boundaryMiny = (useBorder) ? miny + correlationDistance : miny;
final double boundaryMaxy = (useBorder) ? maxy - correlationDistance : maxy;
int N = 0;
if (boundaryMaxx <= boundaryMinx || boundaryMaxy <= boundaryMiny) {
log("ERROR: 'Use border' option of %s nm is not possible: Width = %s nm, Height = %s nm", Utils.rounded(correlationDistance, 4), Utils.rounded(maxx - minx, 3), Utils.rounded(maxy - miny, 3));
return;
} else {
for (int i = molecules.size(); i-- > 0; ) {
final Molecule m = molecules.get(i);
// Optionally ignore molecules that are near the edge of the boundary
if (useBorder && (m.x < boundaryMinx || m.x > boundaryMaxx || m.y < boundaryMiny || m.y > boundaryMaxy))
continue;
N++;
for (int j = molecules.size(); j-- > 0; ) {
if (i == j)
continue;
double d = m.distance2(molecules.get(j));
if (d < maxDistance2) {
H[(int) (Math.sqrt(d) / correlationInterval)]++;
}
}
}
}
double[] r = new double[nBins + 1];
for (int i = 0; i <= nBins; i++) r[i] = i * correlationInterval;
double[] pcf = new double[nBins];
if (N > 0) {
// Note: Convert nm^2 to um^2
final double N_pi = N * Math.PI / 1000000.0;
for (int i = 0; i < nBins; i++) {
// Pair-correlation is the count at the given distance divided by N and the area at distance ri:
// H(r_i) / (N x (pi x (r_i+1)^2 - pi x r_i^2))
pcf[i] = H[i] / (N_pi * (r[i + 1] * r[i + 1] - r[i] * r[i]));
}
}
// The final bin may be empty if the correlation interval was a factor of the correlation distance
if (pcf[pcf.length - 1] == 0) {
r = Arrays.copyOf(r, nBins - 1);
pcf = Arrays.copyOf(pcf, nBins - 1);
} else {
r = Arrays.copyOf(r, nBins);
}
double[][] gr = new double[][] { r, pcf, null };
CorrelationResult result = new CorrelationResult(results.size() + 1, PCPALMMolecules.results.getSource(), boundaryMinx, boundaryMiny, boundaryMaxx, boundaryMaxy, N, correlationInterval, 0, false, gr, true);
results.add(result);
noPlots = WindowManager.getFrame(spatialPlotTitle) == null;
topPlotTitle = frequencyDomainTitle;
plotCorrelation(gr, 0, spatialPlotTitle, "molecules/um^2", true, false);
} else {
// -----------------
// Image correlation in the Frequency Domain
// -----------------
log("Frequency domain analysis");
// Create a binary image for the molecules
ImageProcessor im = PCPALMMolecules.drawImage(molecules, minx, miny, maxx, maxy, nmPerPixel, true, binaryImage);
log("Image scale = %.2f nm/pixel : %d x %d pixels", nmPerPixel, im.getWidth(), im.getHeight());
// Apply a window function to the image to reduce FFT edge artifacts.
if (applyWindow) {
im = applyWindow(im, imageWindow);
}
if (showHighResolutionImage) {
PCPALMMolecules.displayImage(PCPALMMolecules.results.getName() + " " + ((binaryImage) ? "Binary" : "Count") + " Image (high res)", im, nmPerPixel);
}
// Create weight image (including windowing)
ImageProcessor w = createWeightImage(im, applyWindow);
// Store the area of the image in um^2
weightedAreaInPx = areaInPx = im.getWidth() * im.getHeight();
if (applyWindow) {
weightedAreaInPx *= w.getStatistics().mean;
}
area = areaInPx * nmPerPixel * nmPerPixel / 1e6;
weightedArea = weightedAreaInPx * nmPerPixel * nmPerPixel / 1e6;
noOfMolecules = molecules.size();
// Pad the images to the largest scale being investigated by the correlation function.
// Original Sengupta paper uses 800nm for the padding size.
// Limit to within 80% of the minimum dimension of the image.
double maxRadius = correlationDistance / nmPerPixel;
int imageSize = FastMath.min(im.getWidth(), im.getHeight());
if (imageSize < 1.25 * maxRadius)
maxRadius = imageSize / 1.25;
int pad = (int) Math.round(maxRadius);
log("Analysing up to %.0f nm = %d pixels", maxRadius * nmPerPixel, pad);
im = padImage(im, pad);
w = padImage(w, pad);
// // Used for debugging
// {
// ImageProcessor w2 = w.duplicate();
// w2.setMinAndMax(0, 1);
// PCPALMMolecules.displayImage(PCPALMMolecules.results.getName() + " Binary Image Mask", w2, nmPerPixel);
// }
final double peakDensity = getDensity(im);
// Create 2D auto-correlation
double[][] gr;
try {
// Use the FFT library as it is multi-threaded. This may not be in the user's path.
gr = computeAutoCorrelationCurveFFT(im, w, pad, nmPerPixel, peakDensity);
} catch (Exception e) {
// Default to the ImageJ built-in FHT
gr = computeAutoCorrelationCurveFHT(im, w, pad, nmPerPixel, peakDensity);
}
if (gr == null)
return;
// Add the g(r) curve to the results
addResult(peakDensity, gr);
noPlots = WindowManager.getFrame(frequencyDomainTitle) == null;
topPlotTitle = spatialPlotTitle;
// Do not plot r=0 value on the curve
plotCorrelation(gr, 1, frequencyDomainTitle, "g(r)", false, showErrorBars);
}
if (noPlots) {
// Position the plot underneath the other one
Frame f1 = WindowManager.getFrame(topPlotTitle);
if (f1 != null) {
String bottomPlotTitle = (topPlotTitle.equals(spatialPlotTitle) ? frequencyDomainTitle : spatialPlotTitle);
Frame f2 = WindowManager.getFrame(bottomPlotTitle);
if (f2 != null)
f2.setLocation(f2.getLocation().x, f2.getLocation().y + f1.getHeight());
}
}
log("%s domain analysis computed in %s ms", (spatialDomain) ? "Spatial" : "Frequency", Utils.rounded((System.nanoTime() - start) * 1e-6, 4));
log("---");
}
use of ij.process.ImageProcessor in project GDSC-SMLM by aherbert.
the class PCPALMAnalysis method createWeightImage.
/**
* Create a weight image of the same size. All pixels corresponding to the original image area
* are set to 1. A window function is optionally applied.
*
* @param im
* @param applyWindow
* @return The weight image
*/
private ImageProcessor createWeightImage(ImageProcessor im, boolean applyWindow) {
float[] data = new float[im.getWidth() * im.getHeight()];
Arrays.fill(data, 1);
ImageProcessor w = new FloatProcessor(im.getWidth(), im.getHeight(), data, null);
if (applyWindow) {
w = applyWindow(w, imageWindow);
}
return w;
}
Aggregations