public class ConnectedComponent3D
extends java.lang.Object
This class implements multithreaded and linear O(n) 3D particle identification and shape analysis. Surface meshing and 3D visualisation are provided by Bene Schmid's ImageJ 3D Viewer.
This plugin is based on Object_Counter3D by Fabrice P Cordelires and Jonathan Jackson, but with significant speed increases through reduction of recursion and multi-threading. Thanks to Robert Barbour for the suggestion to 'chunk' the stack. Chunking works as follows:
The performance improvement should be in the region of a factor of n if run linearly, and if multithreaded over c processors, speed increase should be in the region of n * c, minus overhead.
Modifier and Type | Field and Description |
---|---|
static int |
BACK
Background value
|
static int |
FORE
Foreground value
|
static int |
LINEAR
Particle joining method
|
static int |
MAPPED
Particle joining method
|
static int |
MULTI
Particle joining method
|
Constructor and Description |
---|
ConnectedComponent3D() |
Modifier and Type | Method and Description |
---|---|
boolean |
dialogItemChanged(ij.gui.GenericDialog gd,
java.awt.AWTEvent e) |
ij.ImagePlus |
displayParticleValues(ij.ImagePlus imp,
int[][] particleLabels,
double[] values,
java.lang.String title)
Create an image showing some particle measurement
|
static ij.ImagePlus |
getBinaryParticle(int p,
ij.ImagePlus imp,
int[][] particleLabels,
int[][] limits,
int padding)
create a binary ImagePlus containing a single particle and which 'just
fits' the particle
|
double[][] |
getCentroids(ij.ImagePlus imp,
int[][] particleLabels,
long[] particleSizes)
Get the centroids of all the particles in real units
|
int[][] |
getChunkRanges(ij.ImagePlus imp,
int nC,
int slicesPerChunk)
Get a 2 d array that defines the z-slices to scan within while connecting
particles within chunkified stacks.
|
org.doube.jama.EigenvalueDecomposition[] |
getEigens(ij.ImagePlus imp,
int[][] particleLabels,
double[][] centroids) |
java.lang.Object[][] |
getEllipsoids(java.util.ArrayList<java.util.List<Point3D>> surfacePoints) |
double[] |
getFerets(java.util.ArrayList<java.util.List<Point3D>> particleSurfaces)
Get the Feret diameter of a surface.
|
int |
getLabelMethod()
Return the value of this instance's labelMethod field
|
java.lang.Object[] |
getMaxDistances(ij.ImagePlus imp,
int[][] particleLabels,
double[][] centroids,
org.doube.jama.EigenvalueDecomposition[] E)
Get the maximum distances from the centroid in x, y, and z axes, and
transformed x, y and z axes
|
double[][] |
getMeanStdDev(ij.ImagePlus imp,
int[][] particleLabels,
long[] particleSizes,
int threshold)
Get the mean and standard deviation of pixel values above a minimum value
for each particle in a particle label work array
|
int |
getNCavities(ij.ImagePlus imp) |
int |
getNChunks(ij.ImagePlus imp,
int slicesPerChunk)
Gets number of chunks needed to divide a stack into evenly-sized sets of
slices.
|
int[][] |
getParticleLimits(ij.ImagePlus imp,
int[][] particleLabels,
int nParticles)
Get the minimum and maximum x, y and z coordinates of each particle
|
java.util.ArrayList<java.util.ArrayList<short[]>> |
getParticleLists(int[][] particleLabels,
int nBlobs,
int w,
int h,
int d) |
java.lang.Object[] |
getParticles(ij.ImagePlus imp,
byte[][] workArray,
int slicesPerChunk,
double minVol,
double maxVol,
int phase) |
java.lang.Object[] |
getParticles(ij.ImagePlus imp,
byte[][] workArray,
int slicesPerChunk,
double minVol,
double maxVol,
int phase,
boolean doExclude)
Get particles, particle labels and sizes from a workArray using an
ImagePlus for scale information
|
java.lang.Object[] |
getParticles(ij.ImagePlus imp,
byte[][] workArray,
int slicesPerChunk,
int phase,
int method) |
java.lang.Object[] |
getParticles(ij.ImagePlus imp,
int slicesPerChunk,
double minVol,
double maxVol,
int phase) |
java.lang.Object[] |
getParticles(ij.ImagePlus imp,
int slicesPerChunk,
double minVol,
double maxVol,
int phase,
boolean doExclude)
Get particles, particle labels and particle sizes from a 3D ImagePlus
|
java.lang.Object[] |
getParticles(ij.ImagePlus imp,
int slicesPerChunk,
int phase) |
long[] |
getParticleSizes(int[][] particleLabels)
Get the sizes of all the particles as a voxel count
|
double[] |
getVolumes(ij.ImagePlus imp,
long[] particleSizes) |
void |
joinBlobs(int b,
int p,
int[][] particleLabels,
java.util.ArrayList<java.util.ArrayList<short[]>> particleLists,
int w)
Join particle p to particle b, relabelling p with b.
|
void |
replaceLabel(int[][] particleLabels,
int m,
int n,
int startZ,
int endZ)
Check whole array replacing m with n
|
void |
replaceLabel(int[][] particleLabels,
int m,
int n,
int startZ,
int endZ,
boolean multithreaded)
Check whole array replacing m with n
|
void |
setLabelMethod(int label)
Set the value of this instance's labelMethod field
|
public static final int FORE
public static final int BACK
public static final int MULTI
public static final int LINEAR
public static final int MAPPED
public java.lang.Object[][] getEllipsoids(java.util.ArrayList<java.util.List<Point3D>> surfacePoints)
public double[][] getMeanStdDev(ij.ImagePlus imp, int[][] particleLabels, long[] particleSizes, int threshold)
imp
- Input image containing pixel valuesparticleLabels
- workArray containing particle labelsparticleSizes
- array of particle sizes as pixel countsthreshold
- restrict calculation to values > ipublic int getNCavities(ij.ImagePlus imp)
public int[][] getParticleLimits(ij.ImagePlus imp, int[][] particleLabels, int nParticles)
imp
- ImagePlus (used for stack size)particleLabels
- work array containing labelled particlesnParticles
- number of particles in the stackpublic org.doube.jama.EigenvalueDecomposition[] getEigens(ij.ImagePlus imp, int[][] particleLabels, double[][] centroids)
public java.lang.Object[] getMaxDistances(ij.ImagePlus imp, int[][] particleLabels, double[][] centroids, org.doube.jama.EigenvalueDecomposition[] E)
imp
- particleLabels
- centroids
- E
- public double[] getFerets(java.util.ArrayList<java.util.List<Point3D>> particleSurfaces)
particleSurfaces
- public static ij.ImagePlus getBinaryParticle(int p, ij.ImagePlus imp, int[][] particleLabels, int[][] limits, int padding)
p
- The particle ID to getimp
- original image, used for calibrationparticleLabels
- work array of particle labelslimits
- x,y and z limits of each particlepadding
- amount of empty space to pad around each particlepublic ij.ImagePlus displayParticleValues(ij.ImagePlus imp, int[][] particleLabels, double[] values, java.lang.String title)
imp
- particleLabels
- values
- list of values whose array indices correspond to
particlelabelstitle
- tag stating what we are displayingpublic double[][] getCentroids(ij.ImagePlus imp, int[][] particleLabels, long[] particleSizes)
imp
- particleLabels
- particleSizes
- public double[] getVolumes(ij.ImagePlus imp, long[] particleSizes)
public java.lang.Object[] getParticles(ij.ImagePlus imp, int slicesPerChunk, double minVol, double maxVol, int phase, boolean doExclude)
imp
- Binary input imageslicesPerChunk
- number of slices per chunk. 2 is generally good.minVol
- minimum volume particle to includemaxVol
- maximum volume particle to includephase
- foreground or background (FORE or BACK)doExclude
- if true, remove particles touching sides of the stackpublic java.lang.Object[] getParticles(ij.ImagePlus imp, int slicesPerChunk, double minVol, double maxVol, int phase)
public java.lang.Object[] getParticles(ij.ImagePlus imp, int slicesPerChunk, int phase)
public java.lang.Object[] getParticles(ij.ImagePlus imp, byte[][] workArray, int slicesPerChunk, int phase, int method)
public java.lang.Object[] getParticles(ij.ImagePlus imp, byte[][] workArray, int slicesPerChunk, double minVol, double maxVol, int phase)
public java.lang.Object[] getParticles(ij.ImagePlus imp, byte[][] workArray, int slicesPerChunk, double minVol, double maxVol, int phase, boolean doExclude)
imp
- input binary imageworkArray
- work arrayslicesPerChunk
- number of slices to use for each chunkminVol
- minimum volume particle to includemaxVol
- maximum volume particle to includephase
- FORE or BACK for foreground or background respectivelypublic int getNChunks(ij.ImagePlus imp, int slicesPerChunk)
imp
- input imageslicesPerChunk
- number of slices per chunkpublic java.util.ArrayList<java.util.ArrayList<short[]>> getParticleLists(int[][] particleLabels, int nBlobs, int w, int h, int d)
public void joinBlobs(int b, int p, int[][] particleLabels, java.util.ArrayList<java.util.ArrayList<short[]>> particleLists, int w)
b
- p
- particleLabels
- array of particle labelsparticleLists
- list of particle voxel coordinatesw
- stack widthpublic int[][] getChunkRanges(ij.ImagePlus imp, int nC, int slicesPerChunk)
nC
- number of chunkspublic void replaceLabel(int[][] particleLabels, int m, int n, int startZ, int endZ)
m
- value to be replacedn
- new valuestartZ
- first z coordinate to checkendZ
- last+1 z coordinate to checkpublic void replaceLabel(int[][] particleLabels, int m, int n, int startZ, int endZ, boolean multithreaded)
m
- value to be replacedn
- new valuestartZ
- first z coordinate to checkendZ
- last+1 z coordinate to checkmultithreaded
- true if label replacement should happen in multiple threadspublic long[] getParticleSizes(int[][] particleLabels)
particleLabels
- public int getLabelMethod()
public void setLabelMethod(int label)
label
- one of ParticleCounter.MULTI or .LINEARpublic boolean dialogItemChanged(ij.gui.GenericDialog gd, java.awt.AWTEvent e)