use of mcib3d.geom.Object3DVoxels in project mcib3d-core by mcib3d.
the class ImageLabeller method getObjects.
// classical default neighborhood for segmentation is 26
public ArrayList<Object3DVoxels> getObjects(ImageHandler mask, boolean connex6) {
if ((spots == null) || (mask != currentMask)) {
if (connex6) {
this.labelSpots6(mask);
} else {
this.labelSpots26(mask);
}
}
ArrayList<Object3DVoxels> objects = new ArrayList<Object3DVoxels>();
int sizeX = mask.sizeX;
short label = 1;
for (Spot s : spots.values()) {
ArrayList<Vox3D> a = s.voxels;
// check size
if ((a.size() >= minSize) && (a.size() <= maxsize)) {
ArrayList voxels3D = new ArrayList();
for (Vox3D vox : a) {
voxels3D.add(new Voxel3D(vox.xy % sizeX, vox.xy / sizeX, vox.z, label));
}
ArrayList noDuplicate = new ArrayList(new HashSet(voxels3D));
// set calibration
Object3DVoxels object3DVoxels = new Object3DVoxels(noDuplicate);
// Object3D_IJUtils.setCalibration(object3DVoxels, mask.getCalibration());
object3DVoxels.setCalibration(mask.getScaleXY(), mask.getScaleZ(), mask.getUnit());
objects.add(object3DVoxels);
label++;
}
}
return objects;
}
use of mcib3d.geom.Object3DVoxels in project mcib3d-core by mcib3d.
the class ImageShort method draw.
@Override
public void draw(Object3D o, int value) {
Object3DVoxels ov;
if (!(o instanceof Object3DVoxels)) {
ov = o.getObject3DVoxels();
} else {
ov = (Object3DVoxels) o;
}
if (value > 65535) {
value = 255;
}
if (value < 0) {
value = 0;
}
short val = (short) value;
for (Voxel3D v : ov.getVoxels()) {
if (contains(v.getX(), v.getY(), v.getZ())) {
pixels[v.getRoundZ()][v.getRoundX() + v.getRoundY() * sizeX] = val;
}
}
}
use of mcib3d.geom.Object3DVoxels in project mcib3d-core by mcib3d.
the class Segment3DSpots method splitSpotWatershed.
public static Object3DVoxels[] splitSpotWatershed(Object3D obj, float rad, float dist) {
ImageInt seg = obj.createSegImage(0, 0, 0, obj.getXmax(), obj.getYmax(), obj.getZmax(), 255);
// seg.show();
ImagePlus segplus = seg.getImagePlus();
segplus.setCalibration(obj.getCalibration());
// return
Object3DVoxels[] res = null;
try {
int cpus = ThreadUtil.getNbCpus();
// FIXME variable multithread
ImageFloat edt3d = EDT.run(seg, 1f, false, cpus);
// 3D filtering of the edt to remove small local maxima
ImageFloat edt3dseeds = FastFilters3D.filterFloatImage(edt3d, FastFilters3D.MEAN, 1, 1, 1, cpus, false);
// edt3d.showDuplicate("edt");
// ImageStack localMax = FastFilters3D.filterFloatImageStack(edt3d.getImageStack(), FastFilters3D.MAXLOCAL, rad, rad, rad, cpus, false);
ImageFloat maxlocal3d = FastFilters3D.filterFloatImage(edt3dseeds, FastFilters3D.MAXLOCAL, rad, rad, rad, cpus, false);
// maxlocal3d.show("max local");
ArrayList<Voxel3D> locals = obj.listVoxels(maxlocal3d, 0);
int nb = locals.size();
// IJ.log("nb=" + nb);
if (nb < 2) {
return null;
}
// look for most far apart local maxima
int i1 = 0;
int i2 = 0;
double dmax = 0.0;
double d;
for (int i = 0; i < nb; i++) {
for (int j = i + 1; j < nb; j++) {
d = locals.get(i).distance(locals.get(j));
if (d > dmax) {
dmax = d;
i1 = i;
i2 = j;
}
}
}
// perform a 2-means clustering
double cx1 = 0;
double cy1 = 0;
double cz1 = 0;
double cx2 = 0;
double cy2 = 0;
double cz2 = 0;
double d1;
double d2;
Voxel3D PP1 = new Voxel3D(locals.get(i1).getX(), locals.get(i1).getY(), locals.get(i1).getZ(), 1);
Voxel3D PP2 = new Voxel3D(locals.get(i2).getX(), locals.get(i2).getY(), locals.get(i2).getZ(), 2);
Voxel3D P1 = new Voxel3D(cx1, cy1, cz1, 0);
Voxel3D P2 = new Voxel3D(cx2, cy2, cz2, 0);
int nb1, nb2;
int nbite = 0;
while ((nb > 2) && ((P1.distance(PP1) > 1) || (P2.distance(PP2) > 1)) && (nbite < 100)) {
nbite++;
cx1 = 0;
cy1 = 0;
cx2 = 0;
cy2 = 0;
cz1 = 0;
cz2 = 0;
nb1 = 0;
nb2 = 0;
P1.setX(PP1.getX());
P1.setY(PP1.getY());
P1.setZ(PP1.getZ());
P2.setX(PP2.getX());
P2.setY(PP2.getY());
P2.setZ(PP2.getZ());
for (Voxel3D local : locals) {
d1 = P1.distance(local);
d2 = P2.distance(local);
if (d1 < d2) {
cx1 += local.getX();
cy1 += local.getY();
cz1 += local.getZ();
nb1++;
} else {
cx2 += local.getX();
cy2 += local.getY();
cz2 += local.getZ();
nb2++;
}
}
cx1 /= nb1;
cy1 /= nb1;
cx2 /= nb2;
cy2 /= nb2;
cz1 /= nb1;
cz2 /= nb2;
PP1.setX(cx1);
PP1.setY(cy1);
PP1.setZ(cz1);
PP2.setX(cx2);
PP2.setY(cy2);
PP2.setZ(cz2);
}
// check minimal distances
double distPP = PP1.distance(PP2);
IJ.log("Centers found for split PP1=" + PP1 + " PP2=" + PP2 + " distance " + distPP);
if (distPP < dist) {
return null;
}
// find closest max local to two barycenters, in case barycenters outside object
Voxel3D PP1closest = new Voxel3D(locals.get(0));
Voxel3D PP2closest = new Voxel3D(locals.get(0));
double dist1 = PP1.distanceSquare(PP1closest);
double dist2 = PP2.distanceSquare(PP2closest);
for (Voxel3D local : locals) {
double dd1 = PP1.distanceSquare(local);
double dd2 = PP2.distanceSquare(local);
if (dd1 < dist1) {
dist1 = dd1;
PP1closest = local;
}
if (dd2 < dist2) {
dist2 = dd2;
PP2closest = local;
}
}
ImageInt seeds = new ImageShort("seeds", seg.sizeX, seg.sizeY, seg.sizeZ);
seeds.setPixel(PP1closest.getRoundX(), PP1closest.getRoundY(), PP1closest.getRoundZ(), 255);
seeds.setPixel(PP2closest.getRoundX(), PP2closest.getRoundY(), PP2closest.getRoundZ(), 255);
// seeds.show();
// Watershed3D_old wat = new Watershed3D_old(edt3d, seeds, 0, 0);
// ImageInt wat2 = wat.getWatershedImage3D();
// ImageHandler edt16 = edt3d.convertToShort(true);
Watershed3D wat = new Watershed3D(edt3d, seeds, 0, 0);
ImageInt wat2 = wat.getWatershedImage3D();
// wat2.show();
// in watershed label starts at 1
Object3DVoxels ob1 = new Object3DVoxels(wat2, 1);
Object3DVoxels ob2 = new Object3DVoxels(wat2, 2);
// IJ.log("split1="+ob1+" split2="+ob2);
// translate objects if needed by miniseg
// ob1.translate(seg.offsetX, seg.offsetY, seg.offsetZ);
// new ImagePlus("wat", wat2.getStack()).show();
res = new Object3DVoxels[2];
res[0] = ob1;
res[1] = ob2;
} catch (Exception e) {
IJ.log("Exception EDT " + e);
}
return res;
}
use of mcib3d.geom.Object3DVoxels in project mcib3d-core by mcib3d.
the class Segment3DSpots method segmentAll.
/**
*/
public void segmentAll() {
segmentedObjects = new ArrayList<Object3D>();
ArrayList<Voxel3D> obj;
int o = 1;
int localThreshold = localValue;
if (labelImage == null) {
this.createLabelImage();
}
// locate seeds
for (int z = 0; z < seedsImage.sizeZ; z++) {
IJ.showStatus("Segmenting slice " + (z + 1));
// IJ.log("Segmenting slice " + (z + 1));
for (int y = 0; y < seedsImage.sizeY; y++) {
for (int x = 0; x < seedsImage.sizeX; x++) {
if (seedsImage.getPixel(x, y, z) > seedsThreshold) {
// LOCAL THRESHOLD
if (localMethod == LOCAL_MEAN) {
localThreshold = (int) localMean(x, y, z);
} else if (localMethod == LOCAL_GAUSS) {
double[] gauss;
gauss = this.gaussianFit(x, y, z, false);
if (gauss != null) {
double thresh = CurveFitter.f(CurveFitter.GAUSSIAN, gauss, GAUSS_PC * gauss[3]);
// IJ.log("gauss sigma : " + gauss[3] + " thresh=" + thresh);
localThreshold = (int) thresh;
}
} else if (localMethod == LOCAL_DIFF) {
localThreshold = (int) Math.max(1, seedsImage.getPixel(x, y, z) - diff);
}
if (localThreshold > 0) {
if (show) {
IJ.log("segmenting spot at : " + x + " " + y + " " + " " + z + " lc=" + localThreshold);
}
}
switch(methodSeg) {
case SEG_CLASSICAL:
obj = this.segmentSpotClassical(x, y, z, localThreshold, o);
break;
case SEG_MAX:
obj = this.segmentSpotMax(x, y, z, localThreshold, o);
break;
case SEG_BLOCK:
obj = this.segmentSpotBlock(x, y, z, localThreshold, o);
break;
default:
obj = this.segmentSpotClassical(x, y, z, localThreshold, o);
break;
}
if ((obj != null) && (obj.size() >= volMin) && (obj.size() <= volMax)) {
segmentedObjects.add(new Object3DVoxels(obj));
// IJ.log("obj size: "+obj.size());
o++;
} else if (obj != null) {
// erase from label image
for (Voxel3D vo : obj) {
labelImage.setPixel(vo.getRoundX(), vo.getRoundY(), vo.getRoundZ(), 0);
}
if (show) {
IJ.log("object volume outside range : " + obj.size());
}
}
}
}
}
}
}
use of mcib3d.geom.Object3DVoxels in project mcib3d-core by mcib3d.
the class FastFilters3D method filterFloatImage.
public static ImageFloat filterFloatImage(ImageFloat stackorig, int filter, Object3DVoxels obj, int nbcpus, boolean showstatus) {
int nbToProcess = stackorig.sizeZ;
if ((filter == TOPHAT) || (filter == CLOSEGRAY) || (filter == OPENGRAY))
nbToProcess *= 2;
// Timer
final Chrono time = new Chrono(nbToProcess);
time.start();
final AbstractLog show = new IJStatus();
final Object3DVoxels object = obj;
// IJ.log("Using java filtering " + voisx + " " + voisy + " " + voisz + " " + filter + " " + nbcpus);
final ImageFloat ima = stackorig;
ImageFloat res = (ImageFloat) ima.createSameDimensions();
if ((filter == MEAN) || (filter == MEDIAN) || (filter == MIN) || (filter == MAX) || (filter == MAXLOCAL) || (filter == TOPHAT) || (filter == VARIANCE) || (filter == CLOSEGRAY) || (filter == OPENGRAY)) {
// PARALLEL
final ImageFloat out = res;
final AtomicInteger ai = new AtomicInteger(0);
final int n_cpus = nbcpus == 0 ? ThreadUtil.getNbCpus() : nbcpus;
int fi = filter;
if ((fi == TOPHAT) || (fi == OPENGRAY)) {
fi = MIN;
}
if (fi == CLOSEGRAY) {
fi = MAX;
}
final int f = fi;
final int dec = (int) Math.ceil((double) ima.sizeZ / (double) n_cpus);
Thread[] threads = ThreadUtil.createThreadArray(n_cpus);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int k = ai.getAndIncrement(); k < n_cpus; k = ai.getAndIncrement()) {
ima.filterGeneric(out, object, dec * k, dec * (k + 1), f, time, show);
}
}
};
}
ThreadUtil.startAndJoin(threads);
// TOPHAT MAX
if ((filter == TOPHAT) || (filter == OPENGRAY)) {
final int f2 = MAX;
final ImageFloat res2 = (ImageFloat) ima.createSameDimensions();
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int k = ai.getAndIncrement(); k < n_cpus; k = ai.getAndIncrement()) {
out.filterGeneric(res2, object, dec * k, dec * (k + 1), f2, time, show);
}
}
};
}
ThreadUtil.startAndJoin(threads);
// TOPHAT DIFFERENCE
if (filter == TOPHAT) {
res = ima.subtractImage(res2);
} else {
res = res2;
}
}
// CLOSING 2nd Step
if (filter == CLOSEGRAY) {
final int f2 = MIN;
final ImageFloat res2 = (ImageFloat) ima.createSameDimensions();
ai.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int k = ai.getAndIncrement(); k < n_cpus; k = ai.getAndIncrement()) {
out.filterGeneric(res2, object, dec * k, dec * (k + 1), f2, time, show);
}
}
};
}
ThreadUtil.startAndJoin(threads);
res = res2;
}
} else if (filter == SOBEL) {
res = ima.sobelFilter();
} else if (filter == ADAPTIVE) {
// res = ima.adaptiveFilter(voisx, voisy, voisz, nbcpus);
}
return res;
}
Aggregations