use of bacmman.processing.neighborhood.EllipsoidalNeighborhood 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.processing.neighborhood.EllipsoidalNeighborhood in project bacmman by jeanollion.
the class Region method getContour.
/**
* @return subset of object's voxels that are in contact with background, edge or other object
*/
public Set<Voxel> getContour() {
// 1 and not 1.5 -> diagonal
EllipsoidalNeighborhood neigh = !is2D() ? new EllipsoidalNeighborhood(1, 1, true) : new EllipsoidalNeighborhood(1, true);
Set<Voxel> res = new HashSet<>();
if (voxels != null) {
/*for (int i = 0; i<neigh.dx.length; ++i) {
neigh.dx[i]-=mask.xMin();
neigh.dy[i]-=mask.yMin();
if (!is2D()) neigh.dz[i]-=mask.zMin();
}
for (Voxel v: getVoxels()) if (touchBorder(v.x, v.y, v.z, neigh, mask)) res.add(v);
*/
for (Voxel v : getVoxels()) if (touchBorderVox(v, neigh))
res.add(v);
} else if (false && roi != null && is2D()) {
// contour do not correspond: it is shifted 1 pixel towards high y & x values.
return roi.getContour(getBounds());
} else {
getMask();
ImageMask.loop(mask, (x, y, z) -> {
if (touchBorder(x, y, z, neigh, mask))
res.add(new Voxel(x + mask.xMin(), y + mask.yMin(), z + mask.zMin()));
});
}
return res;
}
use of bacmman.processing.neighborhood.EllipsoidalNeighborhood in project bacmman by jeanollion.
the class RemoveHotPixels method computeConfigurationData.
@Override
public void computeConfigurationData(int channelIdx, InputImages inputImages) {
configMapF = new HashMapGetCreate<>(new HashMapGetCreate.SetFactory<>());
Image median = new ImageFloat("", inputImages.getImage(channelIdx, 0));
// excludes center pixel // only on same plane
Neighborhood n = new EllipsoidalNeighborhood(1.5, true);
double thld = threshold.getValue().doubleValue();
int frameRadius = this.frameRadius.getValue().intValue();
double fRd = (double) frameRadius;
final Image[][] testMeanTC = testMode.testSimple() ? new Image[inputImages.getFrameNumber()][1] : null;
final Image[][] testMedianTC = testMode.testSimple() ? new Image[inputImages.getFrameNumber()][1] : null;
// perform sliding mean of image
SlidingOperator<Image, Pair<Integer, Image>, Void> operator = new SlidingOperator<Image, Pair<Integer, Image>, Void>() {
@Override
public Pair<Integer, Image> instanciateAccumulator() {
return new Pair(-1, new ImageFloat("", median));
}
@Override
public void slide(Image removeElement, Image addElement, Pair<Integer, Image> accumulator) {
if (frameRadius <= 1) {
// no averaging in time
accumulator.value = addElement;
} else {
if (removeElement != null && addElement != null) {
loop(accumulator.value.getBoundingBox().resetOffset(), (x, y, z) -> {
accumulator.value.setPixel(x, y, z, accumulator.value.getPixel(x, y, z) + (addElement.getPixel(x, y, z) - removeElement.getPixel(x, y, z)) / fRd);
}, true);
} else if (addElement != null) {
loop(accumulator.value.getBoundingBox().resetOffset(), (x, y, z) -> {
accumulator.value.setPixel(x, y, z, accumulator.value.getPixel(x, y, z) + addElement.getPixel(x, y, z) / fRd);
}, true);
} else if (removeElement != null) {
loop(accumulator.value.getBoundingBox().resetOffset(), (x, y, z) -> {
accumulator.value.setPixel(x, y, z, accumulator.value.getPixel(x, y, z) - removeElement.getPixel(x, y, z) / fRd);
}, true);
}
}
// / keep track of current frame
accumulator.key = accumulator.key + 1;
}
@Override
public Void compute(Pair<Integer, Image> accumulator) {
Filters.median(accumulator.value, median, n, true);
// Filters.median(inputImages.getImage(channelIdx, accumulator.key), median, n);
if (testMode.testSimple()) {
testMeanTC[accumulator.key][0] = accumulator.value.duplicate();
testMedianTC[accumulator.key][0] = median.duplicate();
}
loop(median.getBoundingBox().resetOffset(), (x, y, z) -> {
float med = median.getPixel(x, y, z);
if (accumulator.value.getPixel(x, y, z) - med >= thld) {
Voxel v = new Voxel(x, y, z, med);
for (int f = Math.max(0, accumulator.key - frameRadius); f <= accumulator.key; ++f) {
configMapF.getAndCreateIfNecessary(f).add(v);
// Set<Voxel> set = configMapF.getAndCreateIfNecessarySync(f);
// synchronized (set) {set.add(v);}
}
}
});
// not parallele
return null;
}
};
List<Image> imList = Arrays.asList(InputImages.getImageForChannel(inputImages, channelIdx, false));
if (frameRadius >= 1)
SlidingOperator.performSlideLeft(imList, frameRadius, operator);
else
ThreadRunner.parallelExecutionBySegments(i -> operator.compute(new Pair<>(i, imList.get(i))), 0, imList.size(), 100);
if (testMode.testSimple()) {
// first frames are not computed
for (int f = 0; f < frameRadius - 1; ++f) testMeanTC[f][0] = testMeanTC[frameRadius - 1][0];
for (int f = 0; f < frameRadius - 1; ++f) testMedianTC[f][0] = testMedianTC[frameRadius - 1][0];
Core.showImage5D("Sliding median", testMedianTC);
Core.showImage5D("Sliding mean", testMeanTC);
logger.debug("number of dead voxels detected: {}", configMapF.size());
}
}
use of bacmman.processing.neighborhood.EllipsoidalNeighborhood in project bacmman by jeanollion.
the class Curvature method getCurvatureWatershedMap.
public static ImageFloat getCurvatureWatershedMap(final Image edm, final ImageInteger mask, KDTree<Double> curvature) {
final ImageFloat res = new ImageFloat("CurvatureWatershedMap", edm);
final NearestNeighborSearchOnKDTree<Double> search = new NearestNeighborSearchOnKDTree(curvature);
final TreeSet<Voxel> heap = new TreeSet<>(Voxel.getComparator());
final EllipsoidalNeighborhood neigh = new EllipsoidalNeighborhood(1.5, true);
// initialize with the border of objects
BoundingBox.loop(mask.getBoundingBox().resetOffset(), (int x, int y, int z) -> {
if (mask.insideMask(x, y, z) && neigh.hasNullValue(x, y, z, mask, true)) {
double edmValue = edm.getPixel(x, y, z);
search.search(new Point(x + mask.xMin(), y + mask.yMin()));
res.setPixel(x, y, z, search.getSampler().get());
Voxel next;
for (int i = 0; i < neigh.getSize(); ++i) {
next = new Voxel(x + neigh.dx[i], y + neigh.dy[i], 0);
if (!mask.contains(next.x, next.y, next.z) || !mask.insideMask(x, y, z))
continue;
next.value = edm.getPixel(next.x, next.y, 0);
if (next.value > edmValue)
heap.add(next);
}
}
});
Voxel next;
while (!heap.isEmpty()) {
Voxel v = heap.pollFirst();
double value = 0, count = 0;
for (int i = 0; i < neigh.getSize(); ++i) {
next = new Voxel(v.x + neigh.dx[i], v.y + neigh.dy[i], 0);
next.value = edm.getPixel(next.x, next.y, next.z);
if (next.value > v.value)
heap.add(next);
else {
value += res.getPixel(next.x, next.y, 0);
++count;
if (count > 0)
res.setPixel(v.x, v.y, 0, value / count);
}
}
}
return res;
}
use of bacmman.processing.neighborhood.EllipsoidalNeighborhood in project bacmman by jeanollion.
the class MultiScaleWatershedTransform method run.
public void run() {
double rad = lowConnectivity ? 1 : 1.5;
EllipsoidalNeighborhood neigh = segmentedMap.sizeZ() > 1 ? new EllipsoidalNeighborhood(rad, rad, true) : new EllipsoidalNeighborhood(rad, true);
for (Spot s : spots) {
if (s != null) {
for (Voxel v : s.voxels) {
for (int i = 0; i < neigh.getSize(); ++i) {
Voxel n = new Voxel(v.x + neigh.dx[i], v.y + neigh.dy[i], v.z + neigh.dz[i]);
if (segmentedMap.contains(n.x, n.y, n.z) && mask.insideMask(n.x, n.y, n.z)) {
n.value = watershedMaps[s.scale].getPixel(n.x, n.y, n.z);
heap.add(n);
}
}
}
}
}
Score score = generateScore();
List<Voxel> nextProp = new ArrayList<>(neigh.getSize());
Set<Integer> surroundingLabels = fusionCriterion == null || fusionCriterion instanceof DefaultFusionCriterion ? null : new HashSet<>(neigh.getSize());
while (!heap.isEmpty()) {
// Voxel v = heap.poll();
Voxel v = heap.pollFirst();
if (segmentedMap.getPixelInt(v.x, v.y, v.z) > 0)
continue;
score.setUp(v);
for (int i = 0; i < neigh.getSize(); ++i) {
Voxel n = new Voxel(v.x + neigh.dx[i], v.y + neigh.dy[i], v.z + neigh.dz[i]);
if (segmentedMap.contains(n.x, n.y, n.z) && mask.insideMask(n.x, n.y, n.z)) {
int nextLabel = segmentedMap.getPixelInt(n.x, n.y, n.z);
if (nextLabel > 0) {
if (surroundingLabels != null)
surroundingLabels.add(nextLabel);
score.add(n, nextLabel);
} else
nextProp.add(n);
}
}
int currentLabel = score.getLabel();
spots[currentLabel].addVox(v);
// check propagation criterion
for (Voxel n : nextProp) {
n.value = watershedMaps[spots[currentLabel].scale].getPixel(n.x, n.y, n.z);
if (propagationCriterion.continuePropagation(v, n)) {
// if already present in set -> was accessed from lower value -> priority
if (!heap.contains(n))
heap.add(n);
}
}
nextProp.clear();
// check fusion criterion
if (surroundingLabels != null) {
surroundingLabels.remove(currentLabel);
if (!surroundingLabels.isEmpty()) {
Spot currentSpot = spots[currentLabel];
for (int otherLabel : surroundingLabels) {
if (fusionCriterion.checkFusionCriteria(currentSpot, spots[otherLabel], v)) {
currentSpot = currentSpot.fusion(spots[otherLabel]);
}
}
surroundingLabels.clear();
}
}
}
}
Aggregations