use of mcib3d.utils.KDTreeC in project mcib3d-core by mcib3d.
the class Object3DVoxels method computeContours.
/**
* Compute the contours of the object rad=0.5
*/
private void computeContours(ImageInt segImage, int x0, int y0, int z0) {
// IJ.log("computing contours for "+this+" "+x0+" "+y0+" "+z0+" "+xmin+" "+ymin+" "+zmin);
// segImage.show(""+this);
// init kdtree
kdtreeContours = new KDTreeC(3);
kdtreeContours.setScale3(this.resXY, this.resXY, this.resZ);
areaNbVoxels = 0;
areaContactUnit = 0;
areaContactVoxels = 0;
contours = new ArrayList<Voxel3D>();
boolean cont;
double XZ = resXY * resZ;
double XX = resXY * resXY;
int pix0, pix1, pix2, pix3, pix4, pix5, pix6;
int sx = segImage.sizeX;
int sy = segImage.sizeY;
int sz = segImage.sizeZ;
int face;
int class3or4;
int class1 = 0, class2 = 0, class3 = 0, class4 = 0, class5 = 0, class6 = 0;
int val = value;
// special case value=0
if (val == 0) {
val = (int) segImage.getMinAboveValue(0);
}
// int k = vox.getRoundZ() - z0;
for (int k = zmin - z0; k <= zmax - z0; k++) {
if (showStatus) {
// IJ.showStatus("Contours " + (100 * (k - zmin) / (zmax - zmin + 1)) + " % ");
}
for (int j = ymin - y0; j <= ymax - y0; j++) {
for (int i = xmin - x0; i <= xmax - x0; i++) {
cont = false;
if (segImage.contains(i, j, k)) {
pix0 = segImage.getPixelInt(i, j, k);
if (pix0 == val) {
face = 0;
class3or4 = 0;
if (i + 1 < sx) {
pix1 = segImage.getPixelInt(i + 1, j, k);
} else {
pix1 = 0;
}
if (i - 1 >= 0) {
pix2 = segImage.getPixelInt(i - 1, j, k);
} else {
pix2 = 0;
}
if (j + 1 < sy) {
pix3 = segImage.getPixelInt(i, j + 1, k);
} else {
pix3 = 0;
}
if (j - 1 >= 0) {
pix4 = segImage.getPixelInt(i, j - 1, k);
} else {
pix4 = 0;
}
if (k + 1 < sz) {
pix5 = segImage.getPixelInt(i, j, k + 1);
} else {
pix5 = 0;
}
if (k - 1 >= 0) {
pix6 = segImage.getPixelInt(i, j, k - 1);
} else {
pix6 = 0;
}
if (pix1 != val) {
cont = true;
areaContactUnit += XZ;
areaContactVoxels++;
face++;
if (pix2 != val) {
class3or4 = 1;
}
}
if (pix2 != val) {
cont = true;
areaContactUnit += XZ;
areaContactVoxels++;
face++;
}
if (pix3 != val) {
cont = true;
areaContactUnit += XZ;
areaContactVoxels++;
face++;
if (pix4 != val) {
class3or4 = 1;
}
}
if (pix4 != val) {
cont = true;
areaContactUnit += XZ;
areaContactVoxels++;
face++;
}
if (pix5 != val) {
cont = true;
areaContactUnit += XX;
areaContactVoxels++;
face++;
if (pix6 != val) {
class3or4 = 1;
}
}
if (pix6 != val) {
cont = true;
areaContactUnit += XX;
areaContactVoxels++;
face++;
}
if (cont) {
areaNbVoxels++;
Voxel3D voxC = new Voxel3D(i + x0, j + y0, k + z0, val);
contours.add(voxC);
kdtreeContours.add(voxC.getArray(), voxC);
// Surface area estimation of digitized 3D objects using weighted local configurations
if (face == 1) {
class1++;
}
if (face == 2) {
class2++;
}
if (face == 3 && class3or4 == 0) {
class3++;
}
if (face == 3 && class3or4 == 1) {
class4++;
}
if (face == 4) {
class5++;
}
if (face == 5) {
class6++;
}
}
}
}
}
}
}
// IJ.log("contours "+contours.size());
// METHOD LAURENT GOLE FROM Lindblad2005 TO COMPUTE SURFACE
// Surface area estimation of digitized 3D objects using weighted local configurations
double w1 = 0.894, w2 = 1.3409, w3 = 1.5879, w4 = 2.0, w5 = 8.0 / 3.0, w6 = 10.0 / 3.0;
correctedSurfaceArea = (class1 * w1 + class2 * w2 + class3 * w3 + class4 * w4 + class5 * w5 + class6 * w6);
// if (areaNbVoxels == 0) {
// new ImagePlus("MiniSeg 0", segImage.getImageStack()).show();
// IJ.log(" " + x0 + " " + y0 + " " + z0 + " " + xmin + " " + ymin + " " + zmin);
// }
}