A Fiji/ImageJ plugin for 3D object counting with native-style controls and fixed min/max morphology filters.
It extends the workflow of the native 3D Objects Counter (Bolte & Cordelieres 2006) by adding filters for object shape, volume, surface area, Feret diameter, and intensity, while keeping the familiar threshold, size-filter, map, statistics, and macro workflow.
- Native-like
Analyze > 3D Objects Counter+dialog. - Center-slice IsoData threshold as the default starting threshold.
- Live threshold preview on the displayed slice.
- Threshold and slice scrollbars modelled on the native Fiji controls.
- Fixed min/max rows for size and every supported morphology filter.
- Object, surface, centroid, and center-of-mass maps with numbered labels.
- Per-object statistics, native-style summary logging, and progress feedback.
- Macro-recordable command options and a small Java API for batch workflows.
- Optional XY fractal/lacunarity, composite shape, and arborization measurements
behind one
Extended measurements...button. - A separate recursive folder batch command with manifest, object, and within-batch score CSV files.
Requirements:
- Fiji/ImageJ.
- The standard Fiji
3D Objects Counterandmcib3d-coredependencies, which are provided by Fiji's core update sites.
Update-site install:
- In Fiji, choose
Help > Update... > Manage Update Sites. - Tick
3D Objects Counter+in the list. - Apply changes and restart Fiji.
- Run
Analyze > 3D Objects Counter+.
Manual install:
- Build or download
3D_Objects_Counter_Plus-<version>.jar. - Copy it into Fiji's
plugins/folder. - Restart Fiji.
- Run
Analyze > 3D Objects Counter+.
Open a 3D stack, then run Analyze > 3D Objects Counter+.
The dialog starts at the centre slice and applies an IsoData threshold from
that slice. Adjust Threshold to choose the object cutoff; voxels at or above
the threshold are highlighted in the image preview. Use Slice to check the
threshold through the stack without running object counting.
Filters are fixed min/max ranges. Defaults do not remove objects:
| Filter | Default |
|---|---|
| Size (Voxels) | 10 to stack voxel count |
| Sphericity | 0 to 1 |
| Compactness | 0 to 1 |
| Elongation | 1 to Infinity |
| Surface area | 0 to Infinity |
| Mean intensity | 0 to Infinity |
| Max intensity | 0 to Infinity |
| Max Feret diameter | 0 to Infinity |
| Volume | shown only for spatially calibrated images |
Preview runs object counting and keeps the dialog open. OK runs object
counting, creates the selected outputs, and closes the dialog. The progress
bar updates while the full stack is being labelled, measured, and mapped.
Extended measurements... opens a second window. All three groups are off by
default, so existing runs keep the same columns and speed:
Fractal complexity (XY projection)measures the union of the object across z; it is deliberately not a native 3D box count.Composite shape indicesadds RI, SRI, PB, MP, and VSD.Arborization and Sholl measurementsadds skeleton graph and calibrated 5 µm Sholl measurements. It uses Fiji's installed Skeletonize3D. If that backend is unavailable, values are reported as unavailable rather than silently using an unverified substitute.
Enabled groups append these exact result columns:
- Fractal complexity:
Morph_FractalDim_XY,Morph_FractalDim_XY_R2,Morph_LacunarityMean_XY, andMorph_LacunaritySpread_XY. - Composite indices:
Morph_RI,Morph_SRI,Morph_PB,Morph_MP, andMorph_VSD. - Arborization:
Morph_ShollCriticalRadius_um,Morph_ShollCriticalIntersections,Morph_ShollSchoenenIndex,Morph_ShollPrimaryBranches,Morph_SkeletonBranches,Morph_SkeletonJunctions,Morph_SkeletonEndpoints,Morph_SkeletonVoxels, andMorph_ArborizationBackend.
The second window also contains min/max filters for these measurements.
Only the selected group's rows are shown. Cancel, the window close button,
or Escape discards edits; Use Settings applies them to the current run.
The XY fractal calculation uses box sizes 1, 2, 4, 8, 16, 32, and 64 pixels.
It requires projected bounds of at least 8 by 8 pixels, at least 32 foreground
pixels, four valid scales, and a fit R2 of at least 0.9. R2 remains visible as
quality information when the fit is poor, but the fractal dimension and
lacunarity values are reported as unavailable (NaN).
The composite definitions are:
RI = 1 / sphericity(a geometric restatement, not independent information).SRI = SD(centroid-to-surface distance) / mean distance.PB = 1 - spareness.MP = (elongation - 1) / ((elongation - 1) + (flatness - 1)).VSD = log10(Feret diameter^3 / volume).
MP is unavailable for spheres and near-spheres when its denominator is within
1e-9 of zero. Composite values are unavailable for objects smaller than the
fixed reliability floor of 8 voxels or when a prerequisite falls outside its
physical domain; this adds no setting or user input. These indices describe
geometry; they do not by themselves measure activation, disease, or biological
function. Sholl shells are centred on the object centroid and use a fixed 5 um
step.
Run Analyze > 3D Objects Counter+ Batch... and choose one folder. TIFF files
in that folder and its subfolders are found automatically. The first readable
image opens with the familiar settings dialog; batch mode does not ask for
control groups, metadata, output names, or per-image settings.
Images are processed one at a time. Outputs are written beneath:
<input folder>/3D Objects Counter Plus Batch/<batch id>/
batch_manifest.csvlists every discovered image, including failures and images with zero objects, plus the exact macro settings and calibration.batch_objects.csvcontains one row per object with its source image path.batch_scores.csvcontains long-form within-batch population z-scores and empirical midrank percentiles. Scoring needs at least three finite values; constant features have no z-score and a percentile of 50.
The CSV schemas are:
batch_manifest.csv:BatchRunId,SourceRelativePath,SourceLastModified(epoch milliseconds),Status,Error(including non-fatal warnings),ObjectCount,ContributedScoreRows,PixelWidth,PixelHeight,PixelDepth,SpatialUnit,MacroOptions,FractalXYEnabled,CompositesEnabled,ArborizationEnabled,ArborizationBackend, andPluginVersion.batch_objects.csv:BatchRunId,SourceRelativePath,SourceImageIndex,SourceObjectLabel, followed by the normal per-object ResultsTable columns in their existing order.batch_scores.csv:BatchRunId,SourceRelativePath,SourceImageIndex,SourceObjectLabel,Feature,RawValue,RawUnit,ScoringValue,ScoringUnit,WithinBatchZ,WithinBatchPercentile,ValidN,ReferenceMean,ReferenceSD, andReferenceScope.
For each feature, the reference population is every finite, unit-compatible
object value from all successfully processed images in that run. Every score
row states the exact scope as
all successful objects in this BatchRunId. Changing which images are in the
batch changes the batch ID, reference mean, standard deviation, percentiles,
and z-scores by design; the manifest records exactly which images were used.
These scores describe an object's position within the current batch. Objects from the same image or biological sample are not automatically independent replicates, and these scores are not inferential statistics or evidence of a biological difference.
ContributedScoreRows is the number of long-form rows from that image written
to batch_scores.csv, including rows whose score is NaN.
Coordinates, labels, strings, intensity values, and fractal fit R2 are not
scored. Volume, surface, and Feret values are converted to common
micrometre-based units for scoring when the image unit is known. The score CSV
records both the raw and scoring units. With absent or incompatible units, raw
values are retained while that feature's scores are written as NaN across
the whole batch and the manifest records why.
Cancelling leaves an .incomplete marker and temporary files instead of
presenting partial data as completed CSV output.
Redirect measurements to lets you detect objects on one image while measuring
intensity from another open image. Use this when the detection image is a mask
or filtered stack, but intensity statistics should come from the raw channel.
When a redirect is used, the ImageJ log summary names both images, for example
edges.tif redirect to raw.tif: 2 objects detected .... Statistics table and
map window titles keep the detection image title.
X/Y/Z are geometric centroid coordinates. XM/YM/ZM are intensity-weighted
center-of-mass coordinates. These coordinate sets can be identical when the
measurement image is binary or uniform inside each object.
Run the plugin from an ImageJ macro with the active image selected:
run("3D Objects Counter+", "threshold=128");
Options are whitespace-separated. A full call can combine thresholding, size limits, edge exclusion, redirect, filters, and output controls:
run("3D Objects Counter+",
"threshold=128 min=20 max=Infinity " +
"exclude_edges " +
"sphericity>=0.6 volume>=100 " +
"redirect=[raw.tif] " +
"hide_surfaces hide_centroids");
Filters are written directly as macro options using the feature name. Do not
wrap them in filter1=, filter2=, or any other numbered option.
Macro options:
| Option | Meaning | Default |
|---|---|---|
threshold=<int> |
Voxel intensity cutoff for object detection. | 0 |
min=<int> |
Minimum object size in voxels. | 10 |
max=<int> |
Maximum object size in voxels. | Infinity |
max=Infinity or max=inf |
No upper size limit. | Infinity |
exclude_edges |
Exclude objects touching image borders. | Off |
channel=<int> |
Which channel of a hyperstack to measure, 1-based. 0 measures the channel the image is showing. |
0 |
frame=<int> |
Which time point to measure, 1-based. 0 measures the frame the image is showing. |
0 |
measure_fractal_xy |
Add XY-projection fractal and lacunarity columns. | Off |
measure_composites |
Add RI, SRI, PB, MP, and VSD columns. | Off |
measure_arborization |
Add skeleton graph and calibrated Sholl columns. | Off |
redirect=[image title] |
Measure intensity and center of mass from another open image. | None |
<feature><op><value> |
Morphology/intensity filter, for example sphericity>=0.6. |
None |
hide_labels |
Do not show the object label map. | Show |
hide_surfaces |
Do not show the surface map. | Show |
hide_centroids |
Do not show the centroid map. | Show |
hide_centers_of_mass |
Do not show the center-of-mass map. | Show |
hide_centres_of_mass |
British spelling alias for hide_centers_of_mass. |
Show |
hide_stats |
Do not show the statistics table. | Show |
hide_summary |
Do not write the ImageJ log summary. | Show |
Filter syntax is feature>=value, feature<=value, feature>value, or
feature<value. Keep each filter as one token with no spaces. Multiple
filters are ANDed, so an object must pass every filter to remain. Up to 64
filters are supported. Indexed filter options such as filter1= are not
accepted.
Supported filter features and example macro tokens:
| Feature | Meaning | Example |
|---|---|---|
volume |
Object volume in voxels. | volume>=100 |
volume_calibrated |
Object volume in calibrated spatial units cubed. | volume_calibrated>=250 |
surface_area |
Surface area in calibrated spatial units squared. | surface_area<=500 |
sphericity |
Shape roundness, typically 0..1. |
sphericity>=0.6 |
compactness |
Unitless compactness measure. | compactness<=0.8 |
elongation |
Unitless elongation measure. | elongation<2 |
mean_intensity |
Mean intensity from the source or redirect image. | mean_intensity>=500 |
max_intensity |
Maximum intensity from the source or redirect image. | max_intensity<65535 |
feret_diameter_max |
Maximum 3D Feret diameter in calibrated spatial units. | feret_diameter_max>=5 |
Extended filter names are fractal_dim_xy, fractal_r2_xy,
lacunarity_mean_xy, lacunarity_spread_xy, ri, sri, pb, mp, vsd,
sholl_critical_radius_um, sholl_critical_intersections,
sholl_schoenen_index, sholl_primary_branches, skeleton_branches,
skeleton_junctions, skeleton_endpoints, and skeleton_voxels. Referencing
one in a macro filter automatically enables its measurement group.
For example, this keeps objects that pass all three filters:
run("3D Objects Counter+",
"threshold=128 min=20 sphericity>=0.6 volume>=100 elongation<2");
To save results in a batch macro, select the generated table by its title:
open("/path/to/detection.tif");
imageTitle = getTitle();
run("3D Objects Counter+",
"threshold=128 min=20 sphericity>=0.6 " +
"hide_labels hide_surfaces hide_centroids hide_centers_of_mass " +
"hide_summary");
selectWindow("Results for " + imageTitle);
saveAs("Results", "/path/to/detection_oc3dplus.csv");
For redirect macros, the redirect image must already be open. Use bracketed
titles, for example redirect=[raw.tif]. Avoid [ ] quotes, backslashes, or
line breaks in image titles used in macro options.
OC3DPlusParameters params = OC3DPlus.builder()
.threshold(128)
.minSize(20)
.measureFractalXY(true)
.measureCompositeIndices(true)
.addFilter("sphericity", ">=", 0.6)
.build();
OC3DPlusResult result = OC3DPlus.count(imp, params);The public Java API lives under sc.fiji.oc3dplus.api. The main entry point is
OC3DPlus; results are returned as OC3DPlusResult without opening ImageJ
windows or mutating the source image.
3D Objects Counter+ labels thresholded 3D objects with one 26-connected streaming labeller, whatever the bit depth or shape of the input. When extra filters are enabled, it measures morphology and intensity features from the label map, applies the selected ranges, and then builds the requested maps and results from the filtered label image.
The shared labelling, measurement, and map implementation comes from
oc3d-core. Packaging relocates that code into a private Plus namespace inside
the plugin JAR, so users still install one file and different OC3D variants can
carry their tested core versions without classloader collisions.
On a hyperstack it measures one channel and one frame — the displayed position
unless channel=/frame= or the dialog's Measure: row chooses another. A channel
is a separate signal and a frame a separate time point, so objects are never joined
across either. A plain 3D stack is measured exactly as given.
The results a single-channel 8-bit or 16-bit stack produces are held to
column-for-column agreement with the classic Fiji plugin by an equivalence suite,
label numbering included. The handful of columns that are allowed to differ, and
why, are listed in docs/migration/TOLERANCES.md.
Maps to show:
Objects: full labelled object shapes on every occupied Z slice, with object numbers at centroids. All positive labels are displayed as a solid mask while the underlying pixel values retain their numeric object IDs.Surfaces: labelled surface-voxel map with object numbers at centroids.Centroids: point map at geometric centroids.Centers of mass: point map at intensity-weighted centers of mass.
When a run finds thousands of objects, text-number overlays are skipped to keep output map windows lighter. The map pixel labels and statistics table are still produced.
Result tables:
Statistics: per-object measurements, including native-style columns and morphology quantifications.Summary: ImageJ log line with threshold, size range, object count, and morphology means. If measurement redirect is active, the line starts with<detection image> redirect to <measurement image>.
After every completed single-image run, Fiji's status bar also reports the
detected object count, even when the detailed Summary log is hidden.
Enabled extended groups append only their own Morph_* columns. Arborization
also appends Morph_ArborizationBackend, so each object records whether the
standard Fiji backend was used or the measurement was unavailable.
A filtered run labels the volume exactly as an unfiltered one does, then applies the Plus filters to that label map with streaming measurements. Object, surface, centroid, and center-of-mass maps are built from the filtered label image and matching statistics table.
Morph_* statistics columns remain available in filtered results. Values that
cannot be computed are reported as NaN. Shape values such as sphericity,
compactness, elongation, and 3D Feret diameter come from the bounded Plus
measurement path, so they can differ slightly from older mcib3d values.
curl -fL -o mcib3d-core-4.1.7b.jar https://sites.imagej.net/Tboudier/plugins/mcib3d-suite/mcib3d-core-4.1.7b.jar-20250509161435
mvn install:install-file "-Dfile=mcib3d-core-4.1.7b.jar" "-DgroupId=org.framagit.mcib3d" "-DartifactId=mcib3d-core" "-Dversion=4.1.7b" "-Dpackaging=jar" "-DgeneratePom=true"
mvn clean package "-Denforcer.skip=true"The deployable artifact is
target/3D_Objects_Counter_Plus-<version>.jar.
If you use this plugin in published work, please cite it. Citation metadata is in CITATION.cff, and the Zenodo concept DOI always resolves to the latest archived release. For exact reproducibility, cite the version-specific DOI shown on that release's Zenodo record.
When publishing results that use this plugin, please also cite the upstream tools it builds on:
- 3D Objects Counter by Fabrice Cordelieres and Susanne Bolte (Bolte and Cordelieres, J Microsc, 2006, doi:10.1111/j.1365-2818.2006.01706.x).
- mcib3d-core by Thomas Boudier (Ollion et al., Bioinformatics, 2013, doi:10.1093/bioinformatics/btt276).
The plugin as distributed is GPL-3.0-or-later. See LICENSE for the full text.
The original source in this repository is BSD-3-Clause (LICENSE.BSD-3-Clause). The combined work is GPL because the plugin links GPLv3+ libraries it cannot run without — the native 3D Objects Counter and mcib3d-core. LICENSING.md explains what that means for reuse.
Developed by Jamie Malcolm in the Brancaccio Lab at the UK Dementia Research Institute, Imperial College London.
This work was supported by the UK Dementia Research Institute, which receives its core funding from the UK Medical Research Council, the Alzheimer's Society, and Alzheimer's Research UK.
Built on the Fiji / ImageJ ecosystem, Fabrice Cordelieres's 3D Objects Counter, and Thomas Boudier's mcib3d-core.
OC3DPlus.countAll bounds its image-worker pool to the number of inputs and cancels outstanding work
if a worker fails. Fractal measurements for independent objects also run in deterministic indexed
workers for single-image analysis. Arborization remains serial because third-party skeletonizer
reentrancy is not guaranteed, and inner feature workers are disabled during an outer multi-image run
to prevent nested oversubscription. Set the JVM system property oc3dplus.parallelism to a positive
integer to override the single-image feature-worker cap, or to 1 for the serial reference path.