use of mpicbg.imglib.container.shapelist.ShapeList in project TrakEM2 by trakem2.
the class MCCube method getTriangles.
/**
* Create a list of triangles from the specified image data and the
* given isovalue.
* @param volume
* @param thresh
* @return
*/
public static final List<Point3f> getTriangles(final Volume volume, final int thresh) {
final List<Point3f> tri = new ArrayList<Point3f>();
final Carrier car = new Carrier();
car.w = volume.xDim;
car.h = volume.yDim;
car.d = volume.zDim;
car.threshold = thresh + 0.5f;
car.volume = volume;
if (volume instanceof ImgLibVolume && ((ImgLibVolume) volume).getImage().getContainer() instanceof ShapeList) {
getShapeListImageTriangles((ImgLibVolume) volume, car, tri);
} else {
final MCCube cube = new MCCube();
for (int z = -1; z < car.d + 1; z += 1) {
for (int x = -1; x < car.w + 1; x += 1) {
for (int y = -1; y < car.h + 1; y += 1) {
cube.init(x, y, z);
cube.computeEdges(car);
cube.getTriangles(tri, car);
}
}
IJ.showProgress(z, car.d - 2);
}
}
// convert pixel coordinates
for (int i = 0; i < tri.size(); i++) {
final Point3f p = (Point3f) tri.get(i);
p.x = (float) (p.x * volume.pw + volume.minCoord.x);
p.y = (float) (p.y * volume.ph + volume.minCoord.y);
p.z = (float) (p.z * volume.pd + volume.minCoord.z);
}
return tri;
}
use of mpicbg.imglib.container.shapelist.ShapeList in project TrakEM2 by trakem2.
the class MCCube method getShapeListImageTriangles.
/**
* Identical to getTriangles, but iterates only the minimal necessary bounding box, by asking the shapes objects.
*/
private static final void getShapeListImageTriangles(final ImgLibVolume volume, final Carrier car, final List<Point3f> tri) {
final ShapeList sli = (ShapeList) volume.getImage().getContainer();
final ArrayList<ArrayList<Shape>> shapeLists = sli.getShapeLists();
final Area[] sectionAreas = new Area[shapeLists.size()];
// Create one Area for each section, composed of the addition of all Shape instances
{
int next = -1;
for (final ArrayList<Shape> shapeList : shapeLists) {
next++;
if (shapeList.isEmpty()) {
continue;
}
final Area a = new Area(shapeList.get(0));
for (int i = 1; i < shapeList.size(); i++) {
a.add(new Area(shapeList.get(i)));
}
sectionAreas[next] = a;
}
}
// Fuse Area instances for previous and next sections
final Area[] scanAreas = new Area[sectionAreas.length];
for (int i = 0; i < sectionAreas.length; i++) {
if (null == sectionAreas[i])
continue;
final Area a = new Area(sectionAreas[i]);
if (i - 1 < 0 || null == sectionAreas[i - 1]) {
} else
a.add(sectionAreas[i - 1]);
if (i + 1 > sectionAreas.length - 1 || null == sectionAreas[i + 1]) {
} else
a.add(sectionAreas[i + 1]);
scanAreas[i] = a;
}
// Collect the bounds of all subareas in each scanArea:
final HashMap<Integer, ArrayList<Rectangle>> sectionBounds = new HashMap<Integer, ArrayList<Rectangle>>();
for (int i = 0; i < scanAreas.length; i++) {
if (null == scanAreas[i])
continue;
final ArrayList<Rectangle> bs = new ArrayList<Rectangle>();
Polygon pol = new Polygon();
final float[] coords = new float[6];
for (final PathIterator pit = scanAreas[i].getPathIterator(null); !pit.isDone(); pit.next()) {
switch(pit.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
case PathIterator.SEG_LINETO:
pol.addPoint((int) coords[0], (int) coords[1]);
break;
case PathIterator.SEG_CLOSE:
bs.add(pol.getBounds());
pol = new Polygon();
break;
default:
System.out.println("WARNING: unhandled seg type.");
break;
}
}
sectionBounds.put(i, bs);
}
// Add Z paddings on top and bottom
sectionBounds.put(-1, sectionBounds.get(0));
sectionBounds.put(car.d, sectionBounds.get(car.d - 1));
// Scan only relevant areas:
final MCCube cube = new MCCube();
for (int z = -1; z < car.d + 1; z += 1) {
final ArrayList<Rectangle> bs = sectionBounds.get(z);
if (null == bs || bs.isEmpty())
continue;
for (final Rectangle bounds : bs) {
for (int x = bounds.x - 1; x < bounds.x + bounds.width + 2; x += 1) {
for (int y = bounds.y - 1; y < bounds.y + bounds.height + 2; y += 1) {
cube.init(x, y, z);
cube.computeEdges(car);
cube.getTriangles(tri, car);
}
}
}
IJ.showProgress(z, car.d - 2);
}
}
use of mpicbg.imglib.container.shapelist.ShapeList in project TrakEM2 by trakem2.
the class Patch method addAlphaMaskLocal.
/**
* Add the given area, in local coordinates, to the alpha mask, using the given fill value.
*/
public void addAlphaMaskLocal(final Area aLocal, int value) {
if (value < 0)
value = 0;
if (value > 255)
value = 255;
//
CoordinateTransform ct = null;
if (hasCoordinateTransform() && null == (ct = getCT())) {
return;
}
// When the area is larger than the image, sometimes the area fails to be set at all
// Also, intersection accelerates calls to contains(x,y) for complex polygons
final Area a = new Area(new Rectangle(0, 0, (int) (width + 1), (int) (height + 1)));
a.intersect(aLocal);
if (M.isEmpty(a)) {
Utils.log("ROI does not intersect the active image!");
return;
}
ByteProcessor mask = getAlphaMask();
// Use imglib to bypass all the problems with ShapeROI
// Create a Shape image with background and the Area on it with 'value'
final int background = (null != mask && 255 == value) ? 0 : 255;
final ShapeList<UnsignedByteType> shapeList = new ShapeList<UnsignedByteType>(new int[] { (int) width, (int) height, 1 }, new UnsignedByteType(background));
shapeList.addShape(a, new UnsignedByteType(value), new int[] { 0 });
final mpicbg.imglib.image.Image<UnsignedByteType> shapeListImage = new mpicbg.imglib.image.Image<UnsignedByteType>(shapeList, shapeList.getBackground(), "mask");
ByteProcessor rmask = (ByteProcessor) ImageJFunctions.copyToImagePlus(shapeListImage, ImagePlus.GRAY8).getProcessor();
if (hasCoordinateTransform()) {
// inverse the coordinate transform
final TransformMesh mesh = new TransformMesh(ct, meshResolution, o_width, o_height);
final TransformMeshMapping mapping = new TransformMeshMapping(mesh);
rmask = (ByteProcessor) mapping.createInverseMappedImageInterpolated(rmask);
}
if (null == mask) {
// There wasn't a mask, hence just set it
mask = rmask;
} else {
final byte[] b1 = (byte[]) mask.getPixels();
final byte[] b2 = (byte[]) rmask.getPixels();
// Whatever is not background in the new mask gets set on the old mask
for (int i = 0; i < b1.length; i++) {
// background pixel in new mask
if (background == (b2[i] & 0xff))
continue;
// replace old pixel with new pixel
b1[i] = b2[i];
}
}
setAlphaMask(mask);
}
Aggregations