use of uk.ac.sussex.gdsc.ij.foci.ObjectAnalyzer.ObjectCentre in project gdsc by aherbert.
the class NucleiOutline_PlugIn method divideLargeObjects.
/**
* Divide objects that are too large. If any objects were divided then the original object mask is
* updated in-place and returned.
*
* @param bp the original object mask
* @param oa the object analyzer
* @param maxPixelCount the maximum size in pixels for an object
* @return the updated object mask (or null)
*/
private static ByteProcessor divideLargeObjects(ByteProcessor bp, ObjectAnalyzer oa, int maxPixelCount) {
final int maxObject = oa.getMaxObject();
final ObjectCentre[] objectData = oa.getObjectCentres();
// Divide those that are too large
final IntArrayList toDivide = new IntArrayList();
for (int i = 1; i <= maxObject; i++) {
if (objectData[i].getSize() > maxPixelCount) {
toDivide.add(i);
}
}
if (!toDivide.isEmpty()) {
final int[] mask = oa.getObjectMask();
final byte[] original = (byte[]) bp.getPixels();
final byte[] tmp = new byte[mask.length];
// Move each object to divide from the original to a temp image
toDivide.forEach(object -> {
for (int i = 0; i < mask.length; i++) {
if (mask[i] == object) {
original[i] = 0;
tmp[i] = (byte) 255;
}
}
});
// Watershed the new temp image
final EDM edm = new EDM();
final ByteProcessor tmpIp = new ByteProcessor(bp.getWidth(), bp.getHeight(), tmp);
// The watershed respects the ImageJ setting for Binary processor inversion based on
// the input ImagePlus. Here it is null and so no need to invert.
edm.setup("watershed", null);
edm.run(tmpIp);
IJ.showStatus("");
// Re-create the objects
bp.copyBits(tmpIp, 0, 0, Blitter.ADD);
return bp;
}
return null;
}
use of uk.ac.sussex.gdsc.ij.foci.ObjectAnalyzer.ObjectCentre in project gdsc by aherbert.
the class FrapAnalysis_PlugIn method extractBleachedRegions.
private LocalList<Pair<Integer, Roi>> extractBleachedRegions(final ImageStack events) {
// Post-process the events to join contiguous regions and remove speckles
IJ.showStatus("!Extracting bleached regions...");
final LocalList<Pair<Integer, Roi>> rois = new LocalList<>();
for (int i = 1; i <= events.size(); i++) {
final ByteProcessor bp = (ByteProcessor) events.getProcessor(i);
// Find objects in each frame
final ObjectAnalyzer oa = new ObjectAnalyzer(bp);
oa.setMinObjectSize(settings.minRegionSize);
if (oa.getMaxObject() != 0) {
ImageJUtils.log("Detected %s on frame %d:", TextUtils.pleural(oa.getMaxObject(), "region"), i);
final Roi[] outlines = oa.getObjectOutlines();
final ObjectCentre[] centres = oa.getObjectCentres();
for (int j = 1; j < outlines.length; j++) {
ImageJUtils.log(" [%d] (%.2f,%.2f) = %s pixels", j, intersect.x + centres[j].getCentreX(), intersect.y + centres[j].getCentreY(), centres[j].getSize());
// Store 0-based index for the bleaching event
rois.add(Pair.create(i - 1, outlines[j]));
}
}
}
IJ.protectStatusBar(false);
return rois;
}
use of uk.ac.sussex.gdsc.ij.foci.ObjectAnalyzer.ObjectCentre in project gdsc by aherbert.
the class AssignFociToObjects_PlugIn method run.
/**
* {@inheritDoc}
*/
@Override
public void run(ImageProcessor ip) {
if (!showDialog()) {
return;
}
final ArrayList<Search[]> searchGrid = createDistanceGrid(settings.radius);
createResultsTables();
final ObjectAnalyzer oa = new ObjectAnalyzer(ip);
if (settings.removeSmallObjects) {
oa.setMinObjectSize(settings.minSize);
}
oa.setEightConnected(settings.eightConnected);
final int[] objectMask = oa.getObjectMask();
final int maxx = ip.getWidth();
final int maxy = ip.getHeight();
final double maxD2 = settings.radius * settings.radius;
// Assign each foci to the nearest object
final int[] count = new int[oa.getMaxObject() + 1];
final int[] found = new int[results.size()];
final double[] d2 = new double[found.length];
Arrays.fill(d2, -1);
for (int i = 0; i < results.size(); i++) {
final int[] result = results.get(i);
final int x = result[0];
final int y = result[1];
// Check within the image
if (x < 0 || x >= maxx || y < 0 || y >= maxy) {
continue;
}
int index = y * maxx + x;
if (objectMask[index] != 0) {
count[objectMask[index]]++;
found[i] = objectMask[index];
d2[i] = 0;
continue;
}
// Search for the closest object(s)
final int[] closestCount = new int[count.length];
// Scan wider and wider from 0,0 until we find an object.
for (final Search[] next : searchGrid) {
if (next[0].d2 > maxD2) {
break;
}
boolean ok = false;
for (final Search s : next) {
final int xx = x + s.x;
final int yy = y + s.y;
if (xx < 0 || xx >= maxx || yy < 0 || yy >= maxy) {
continue;
}
index = yy * maxx + xx;
if (objectMask[index] != 0) {
ok = true;
closestCount[objectMask[index]]++;
}
}
if (ok) {
// Get the object with the highest count
int maxCount = 0;
for (int j = 1; j < closestCount.length; j++) {
if (closestCount[maxCount] < closestCount[j]) {
maxCount = j;
}
}
// Assign
count[maxCount]++;
found[i] = maxCount;
d2[i] = next[0].d2;
break;
}
}
}
final ObjectCentre[] centres = oa.getObjectCentres();
// We must ignore those that are too small/big
final int[] idMap = new int[count.length];
for (int i = 1; i < count.length; i++) {
idMap[i] = i;
if (centres[i].getSize() < settings.minSize || (settings.maxSize != 0 && centres[i].getSize() > settings.maxSize)) {
idMap[i] = -i;
}
}
// TODO - Remove objects from the output image ?
showMask(oa, found, idMap);
// Show the results
final DescriptiveStatistics stats = new DescriptiveStatistics();
final DescriptiveStatistics stats2 = new DescriptiveStatistics();
final StringBuilder sb = new StringBuilder();
for (int i = 1, j = 0; i < count.length; i++) {
sb.append(imp.getTitle());
sb.append('\t').append(i);
sb.append('\t').append(MathUtils.rounded(centres[i].getCentreX()));
sb.append('\t').append(MathUtils.rounded(centres[i].getCentreY()));
sb.append('\t').append(centres[i].getSize());
if (idMap[i] > 0) {
// Include this object
sb.append("\tTrue");
stats.addValue(count[i]);
} else {
// Exclude this object
sb.append("\tFalse");
stats2.addValue(count[i]);
}
sb.append('\t').append(count[i]);
sb.append('\n');
// Flush before 10 lines to ensure auto-layout of columns
if (i >= 9 && j++ == 0) {
resultsWindow.append(sb.toString());
sb.setLength(0);
}
}
resultsWindow.append(sb.toString());
// Histogram the count
if (settings.showHistogram) {
final int max = (int) stats.getMax();
final double[] xvalues = new double[max + 1];
final double[] yvalues = new double[xvalues.length];
for (int i = 1; i < count.length; i++) {
if (idMap[i] > 0) {
yvalues[count[i]]++;
}
}
double ymax = 0;
for (int i = 0; i <= max; i++) {
xvalues[i] = i;
if (ymax < yvalues[i]) {
ymax = yvalues[i];
}
}
final String title = TITLE + " Histogram";
final Plot plot = new Plot(title, "Count", "Frequency");
plot.addPoints(xvalues, yvalues, Plot.LINE);
plot.setLimits(0, xvalues[xvalues.length - 1], 0, ymax);
plot.addLabel(0, 0, String.format("N = %d, Mean = %s", (int) stats.getSum(), MathUtils.rounded(stats.getMean())));
plot.draw();
plot.setColor(Color.RED);
plot.drawLine(stats.getMean(), 0, stats.getMean(), ymax);
ImageJUtils.display(title, plot);
}
// Show the summary
sb.setLength(0);
sb.append(imp.getTitle());
sb.append('\t').append(oa.getMaxObject());
sb.append('\t').append(stats.getN());
sb.append('\t').append(results.size());
sb.append('\t').append((int) stats.getSum());
sb.append('\t').append((int) stats2.getSum());
sb.append('\t').append(results.size() - (int) (stats.getSum() + stats2.getSum()));
sb.append('\t').append(stats.getMin());
sb.append('\t').append(stats.getMax());
sb.append('\t').append(MathUtils.rounded(stats.getMean()));
sb.append('\t').append(MathUtils.rounded(stats.getPercentile(50)));
sb.append('\t').append(MathUtils.rounded(stats.getStandardDeviation()));
summaryWindow.append(sb.toString());
if (!settings.showDistances) {
return;
}
sb.setLength(0);
for (int i = 0, j = 0; i < results.size(); i++) {
final int[] result = results.get(i);
final int x = result[0];
final int y = result[1];
// Check within the image
if (x < 0 || x >= maxx || y < 0 || y >= maxy) {
continue;
}
sb.append(imp.getTitle());
sb.append('\t').append(i + 1);
sb.append('\t').append(x);
sb.append('\t').append(y);
if (found[i] > 0) {
sb.append('\t').append(found[i]);
if (idMap[found[i]] > 0) {
sb.append("\tTrue\t");
} else {
sb.append("\tFalse\t");
}
sb.append(MathUtils.rounded(Math.sqrt(d2[i])));
sb.append('\n');
} else {
sb.append("\t\t\t\n");
}
// Flush before 10 lines to ensure auto-layout of columns
if (i >= 9 && j++ == 0) {
distancesWindow.append(sb.toString());
sb.setLength(0);
}
}
distancesWindow.append(sb.toString());
}
use of uk.ac.sussex.gdsc.ij.foci.ObjectAnalyzer.ObjectCentre in project gdsc by aherbert.
the class ObjectAnalyzerTest method checkGetObjectCentres.
@Test
void checkGetObjectCentres() {
final int maxx = 4;
final int maxy = 3;
final byte[] image = { // @formatter:off
0, 0, 3, 4, 0, 3, 0, 0, 0, 3, 7, 7 };
// @formatter:on
final ObjectAnalyzer oa = new ObjectAnalyzer(new ByteProcessor(maxx, maxy, image));
oa.getMaxObject();
final ObjectCentre[] centres = { // @formatter:off
null, new ObjectCentre(2, 0, 1), new ObjectCentre(3, 0, 1), new ObjectCentre(1, 1.5, 2), new ObjectCentre(2.5, 2, 2) };
// @formatter:on
Assertions.assertArrayEquals(centres, oa.getObjectCentres());
}
Aggregations