use of bacmman.data_structure.Voxel in project bacmman by jeanollion.
the class SubPixelLocalizator method getPeaks.
public static List<Point> getPeaks(Image img, List<Region> objects) {
List<Point> peaks = new ArrayList<>(objects.size());
for (Region o : objects) {
// get max value within map
double max = Double.NEGATIVE_INFINITY;
Voxel maxV = null;
for (Voxel v : o.getVoxels()) {
double value = img.getPixel(v.x, v.y, v.z);
if (value > max) {
max = value;
maxV = v;
}
}
if (img.sizeZ() > 1)
peaks.add(new Point(maxV.x, maxV.y, maxV.z));
else
peaks.add(new Point(maxV.x, maxV.y));
}
return peaks;
}
use of bacmman.data_structure.Voxel in project bacmman by jeanollion.
the class RegionCluster method getInteface.
public static <I extends InterfaceRegion<I>> I getInteface(Region o1, Region o2, ImageInteger labelImage, InterfaceFactory<Region, I> interfaceFactory) {
EllipsoidalNeighborhood neigh = labelImage.sizeZ() > 1 ? new EllipsoidalNeighborhood(1, 1, true) : new EllipsoidalNeighborhood(1, true);
Region min;
int otherLabel;
I inter = interfaceFactory.create(o1, o2);
if (o1.getVoxels().size() <= o2.getVoxels().size()) {
min = o1;
otherLabel = o2.getLabel();
} else {
min = o2;
otherLabel = o1.getLabel();
}
int xx, yy, zz;
for (Voxel v : min.getVoxels()) {
for (int i = 0; i < neigh.dx.length; ++i) {
xx = v.x + neigh.dx[i];
yy = v.y + neigh.dy[i];
zz = v.z + neigh.dz[i];
if (labelImage.contains(xx, yy, zz) && labelImage.getPixelInt(xx, yy, zz) == otherLabel)
inter.addPair(v, new Voxel(xx, yy, zz));
}
}
return inter;
}
use of bacmman.data_structure.Voxel in project bacmman by jeanollion.
the class RegionCluster method setInterfaces.
protected void setInterfaces(boolean background, boolean lowConnectivity) {
Map<Integer, Region> objects = new HashMap<>();
for (Region o : population.getRegions()) objects.put(o.getLabel(), o);
if (background) {
backgroundRegion = new Region(new HashSet<>(), 0, population.getImageProperties(), population.getImageProperties().sizeZ() == 1, population.getImageProperties().getScaleXY(), population.getImageProperties().getScaleZ());
objects.put(0, backgroundRegion);
}
ImageInteger inputLabels = population.getLabelMap();
Voxel n = new Voxel(0, 0, 0);
int otherLabel;
int[][] neigh = inputLabels.sizeZ() > 1 ? (lowConnectivity ? ImageLabeller.neigh3DLowHalf : ImageLabeller.neigh3DHalf) : (lowConnectivity ? ImageLabeller.neigh2D4Half : ImageLabeller.neigh2D8Half);
for (Region o : population.getRegions()) {
for (Voxel vox : o.getVoxels()) {
for (int i = 0; i < neigh.length; ++i) {
// only forward for interaction with other spots & background
n.x = vox.x + neigh[i][0];
n.y = vox.y + neigh[i][1];
n.z = vox.z + neigh[i][2];
if (inputLabels.contains(n.x, n.y, n.z) && foregroundMask.insideMask(n.x, n.y, n.z)) {
otherLabel = inputLabels.getPixelInt(n.x, n.y, n.z);
if (otherLabel != o.getLabel()) {
if (background || otherLabel != 0) {
// to avoid having the same instance of voxel as in the region, because voxel can overlap & voxel can be used to store values interface-wise
InterfaceRegion inter = getInterface(o, objects.get(otherLabel), true);
if (otherLabel > o.getLabel())
inter.addPair(vox.duplicate(), n.duplicate());
else
inter.addPair(n.duplicate(), vox.duplicate());
}
}
} else if (background) {
InterfaceRegion inter = getInterface(o, objects.get(0), true);
inter.addPair(n.duplicate(), vox.duplicate());
}
if (background) {
// backward for background only
n.x = vox.x - neigh[i][0];
n.y = vox.y - neigh[i][1];
n.z = vox.z - neigh[i][2];
if (inputLabels.contains(n.x, n.y, n.z)) {
otherLabel = inputLabels.getPixelInt(n.x, n.y, n.z);
if (background && otherLabel == 0) {
InterfaceRegion inter = getInterface(o, objects.get(otherLabel), true);
inter.addPair(n.duplicate(), vox.duplicate());
}
} else {
InterfaceRegion inter = getInterface(o, objects.get(0), true);
inter.addPair(n.duplicate(), vox.duplicate());
}
}
}
}
}
if (verbose)
logger.debug("Interface collection: nb of interfaces:" + interfaces.size());
}
use of bacmman.data_structure.Voxel in project bacmman by jeanollion.
the class BacteriaSpineFactory method getSpineInSkeletonDirection.
private static <T extends Localizable> List<PointContainer2<Vector, Double>> getSpineInSkeletonDirection(ImageMask mask, CircularNode<T> s1, CircularNode<T> s2, List<PointContainer2<Vector, Double>> skeleton, int persistanceRadius, boolean firstNext, Offset logOff) {
List<PointContainer2<Vector, Double>> sp = new ArrayList<>();
Vector skDir = SlidingVector.getMeanVector2D(skeleton.stream().skip(firstNext ? 0 : skeleton.size() - persistanceRadius).limit(persistanceRadius).map(p -> p.getContent1()));
Vector spineDir = skDir.duplicate().normalize().rotateXY90();
if (!firstNext)
spineDir.reverseOffset();
Point lastPoint = skeleton.get(firstNext ? 0 : skeleton.size() - 1);
List<CircularNode<T>> bucketFirst = new ArrayList<>();
while (true) {
// within loop there is a condition of inclusion of point in bacteria
Point nextPoint = lastPoint.duplicate().translate(spineDir);
// get direction of current point according to contour
Point c1 = getIntersectionWithContour(mask, nextPoint, skDir.duplicate().multiply(-1), s1, bucketFirst, logOff);
// push
s1 = bucketFirst.get(0);
Point c2 = getIntersectionWithContour(mask, nextPoint, skDir.duplicate(), s2, bucketFirst, logOff);
// push
s2 = bucketFirst.get(0);
PointContainer2<Vector, Double> next = PointContainer2.fromPoint(nextPoint, Vector.vector2D(c1, c2), 0d);
if (imageDisp != null)
logger.debug("extend skeleton {}: [{};{}] -> {}", firstNext ? "up" : "down", c1.duplicate().translate(logOff), c2.duplicate().translate(logOff), next.duplicate().translate(logOff));
sp.add(next);
// stop condition
Point nextPoint2 = next.duplicate().translate(spineDir);
Voxel nextVox2 = nextPoint2.asVoxel();
if (!mask.containsWithOffset(nextVox2.x, nextVox2.y, mask.zMin()) || !mask.insideMaskWithOffset(nextVox2.x, nextVox2.y, mask.zMin())) {
// adjust to contour. First search is middle point between the 2 sides points
adjustPointToContour(next, spineDir, CircularNode.getMiddlePoint(s1, s2, firstNext), bucketFirst);
if (sp.size() > 2) {
// check that adjusted point is after previous point AND not too close to previous point (if too close may cause projection issues)
Point ref = sp.get(sp.size() - 3);
if (// adjusted before previous
sp.get(sp.size() - 2).distSqXY(ref) > next.distSqXY(ref))
// adjusted before previous
sp.remove(sp.size() - 2);
else // adjusted too close to previous
if (sp.get(sp.size() - 2).dist(sp.get(sp.size() - 1)) < 0.25)
sp.remove(sp.size() - 2);
}
break;
}
lastPoint = next;
}
// check direction of last point: if the norm is too small direction is not precise -> take direction of previous one keeping the norm
if (sp.size() > 1) {
double norm = sp.get(sp.size() - 1).getContent1().norm();
if (norm < 3) {
// minimal norm
if (norm < 2)
norm = 2;
sp.get(sp.size() - 1).setContent1(sp.get(sp.size() - 2).getContent1().duplicate().normalize().multiply(norm));
}
}
return sp;
}
use of bacmman.data_structure.Voxel in project bacmman by jeanollion.
the class BacteriaSpineFactory method getEdtCenter.
private Voxel getEdtCenter(ImageMask mask) {
Image edt = EDT.transform(mask, true, 1, 1, false);
Voxel[] max = new Voxel[1];
ImageMask.loopWithOffset(mask, (x, y, z) -> {
float edtV = edt.getPixelWithOffset(x, y, z);
if (max[0] == null || edtV > max[0].value)
max[0] = new Voxel(x, y, z, edtV);
});
return max[0];
}
Aggregations