use of ij.process.ByteProcessor 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);
}
use of ij.process.ByteProcessor in project TrakEM2 by trakem2.
the class Patch method getAlphaMask.
/**
* Return a new {@link ByteProcessor} representing the alpha mask, if any, over the pixel data.
* @return null if there isn't one, or if the mask image could not be loaded.
*/
public synchronized ByteProcessor getAlphaMask() {
if (0 == alpha_mask_id)
return null;
final String path = createAlphaMaskFilePath(alpha_mask_id);
// Expects a zip file containing one single TIFF file entry
ZipInputStream zis = null;
try {
zis = new ZipInputStream(new FileInputStream(path));
// prepares the entry for reading
final ZipEntry ze = zis.getNextEntry();
// Assume the first entry is the mask
final ImageProcessor mask = new FileOpener(new TiffDecoder(zis, ze.getName()).getTiffInfo()[0]).open(false).getProcessor();
if (mask.getWidth() != o_width || mask.getHeight() != o_height) {
Utils.log2("Mask has improper dimensions: " + mask.getWidth() + " x " + mask.getHeight() + " for patch #" + this.id + " which is of " + o_width + " x " + o_height);
return null;
}
return (ByteProcessor) (mask.getClass() == ByteProcessor.class ? mask : mask.convertToByte(false));
} catch (final Throwable t) {
Utils.log2("Could not load alpha mask for patch #" + this.id + " from file " + path);
IJError.print(t);
return null;
} finally {
try {
if (null != zis)
zis.close();
} catch (final Exception e) {
IJError.print(e);
}
}
}
use of ij.process.ByteProcessor in project TrakEM2 by trakem2.
the class Blending method setBlendingMask.
/**
* Returns true if a new mask has been set to Patch p.
*/
private static boolean setBlendingMask(final Patch p, Set<Patch> overlapping, final Map<Patch, TransformMesh> meshes, final boolean respect_current_mask) {
Utils.log2("Blending " + p);
if (overlapping.contains(p)) {
overlapping = new HashSet<Patch>(overlapping);
overlapping.remove(p);
}
final AffineTransform at = p.getAffineTransform();
final TransformMesh mesh = meshes.get(p);
ByteProcessor mask = null;
if (respect_current_mask) {
mask = p.getAlphaMask();
}
if (null == mask) {
mask = new ByteProcessor(p.getOWidth(), p.getOHeight());
mask.setValue(255);
mask.fill();
}
final byte[] pix = (byte[]) mask.getPixels();
final Point2D.Double po = new Point2D.Double();
final double[] fo = new double[2];
final int p_o_width = p.getOWidth();
final int p_o_height = p.getOHeight();
int next = 0;
// the self as well
final double[] weights = new double[overlapping.size() + 1];
int masked = 0;
for (int y = 0; y < p_o_height; y++) {
if (Thread.currentThread().isInterrupted())
return false;
for (int x = 0; x < p_o_width; x++) {
// transform x,y to world coords
if (null != mesh) {
fo[0] = x;
fo[1] = y;
mesh.applyInPlace(fo);
po.x = fo[0];
po.y = fo[1];
} else {
po.x = x;
po.y = y;
}
at.transform(po, po);
fo[0] = po.x;
fo[1] = po.y;
// debug:
if (0 == x && 0 == y) {
Utils.log2("point 0,0 goes to " + fo[0] + ", " + fo[1]);
}
// check if it intersects any Patch
next = 0;
for (final Patch other : overlapping) {
final double weight = intersects(fo, other, meshes.get(other));
if (weight > 0)
weights[next++] = weight;
}
final int i = y * p_o_width + x;
if (respect_current_mask) {
// Don't compute if no overlap or if current mask value is zero
if (next > 0 && pix[i] != 0) {
// the weight of Patch p, added last
weights[next++] = computeWeight(x, y, p_o_width, p_o_height);
double sum = 0;
for (int f = 0; f < next; f++) sum += weights[f];
pix[i] = (byte) ((int) (255 * (weights[next - 1] / sum) * ((pix[i] & 0xff) / 255.0f)));
masked++;
}
// else leave current value untouched
} else if (next > 0) {
// Overwritting current mask
// the weight of Patch p, added last
weights[next++] = computeWeight(x, y, p_o_width, p_o_height);
double sum = 0;
for (int f = 0; f < next; f++) sum += weights[f];
pix[i] = (byte) ((int) (255 * (weights[next - 1] / sum)));
masked++;
}
}
}
Utils.log2("Masked = " + masked + " for " + p);
if (masked > 0) {
p.setAlphaMask(mask);
return true;
}
Utils.log("Nothing to blend in image " + p);
return false;
}
use of ij.process.ByteProcessor in project TrakEM2 by trakem2.
the class Utils method fireLUT.
/**
* Returns a byte[3][256] containing the colors of the fire LUT.
*/
public static final IndexColorModel fireLUT() {
final ImagePlus imp = new ImagePlus("fire", new ByteProcessor(1, 1));
IJ.run(imp, "Fire", "");
return (IndexColorModel) imp.getProcessor().getColorModel();
}
use of ij.process.ByteProcessor in project TrakEM2 by trakem2.
the class NonLinearTransform method visualize.
// FIXME this takes way too much memory
public void visualize() {
final int density = Math.max(width, height) / 32;
final int border = Math.max(width, height) / 8;
final double[][] orig = new double[width * height][2];
final double[][] trans = new double[height * width][2];
final double[][] gridOrigVert = new double[width * height][2];
final double[][] gridTransVert = new double[width * height][2];
final double[][] gridOrigHor = new double[width * height][2];
final double[][] gridTransHor = new double[width * height][2];
final FloatProcessor magnitude = new FloatProcessor(width, height);
final FloatProcessor angle = new FloatProcessor(width, height);
final ColorProcessor quiver = new ColorProcessor(width, height);
final ByteProcessor empty = new ByteProcessor(width + 2 * border, height + 2 * border);
quiver.setLineWidth(1);
quiver.setColor(Color.green);
final GeneralPath quiverField = new GeneralPath();
float minM = 1000, maxM = 0;
float minArc = 5, maxArc = -6;
int countVert = 0, countHor = 0, countHorWhole = 0;
for (int i = 0; i < width; i++) {
countHor = 0;
for (int j = 0; j < height; j++) {
final double[] position = { (double) i, (double) j };
final double[] posExpanded = kernelExpand(position);
final double[] newPosition = multiply(beta, posExpanded);
orig[i * j][0] = position[0];
orig[i * j][1] = position[1];
trans[i * j][0] = newPosition[0];
trans[i * j][1] = newPosition[1];
double m = (position[0] - newPosition[0]) * (position[0] - newPosition[0]);
m += (position[1] - newPosition[1]) * (position[1] - newPosition[1]);
m = Math.sqrt(m);
magnitude.setf(i, j, (float) m);
minM = Math.min(minM, (float) m);
maxM = Math.max(maxM, (float) m);
final double a = Math.atan2(position[0] - newPosition[0], position[1] - newPosition[1]);
minArc = Math.min(minArc, (float) a);
maxArc = Math.max(maxArc, (float) a);
angle.setf(i, j, (float) a);
if (i % density == 0 && j % density == 0)
drawQuiverField(quiverField, position[0], position[1], newPosition[0], newPosition[1]);
if (i % density == 0) {
gridOrigVert[countVert][0] = position[0] + border;
gridOrigVert[countVert][1] = position[1] + border;
gridTransVert[countVert][0] = newPosition[0] + border;
gridTransVert[countVert][1] = newPosition[1] + border;
countVert++;
}
if (j % density == 0) {
gridOrigHor[countHor * width + i][0] = position[0] + border;
gridOrigHor[countHor * width + i][1] = position[1] + border;
gridTransHor[countHor * width + i][0] = newPosition[0] + border;
gridTransHor[countHor * width + i][1] = newPosition[1] + border;
countHor++;
countHorWhole++;
}
}
}
magnitude.setMinAndMax(minM, maxM);
angle.setMinAndMax(minArc, maxArc);
// System.out.println(" " + minArc + " " + maxArc);
final ImagePlus magImg = new ImagePlus("Magnitude of Distortion Field", magnitude);
magImg.show();
// ImagePlus angleImg = new ImagePlus("Angle of Distortion Field Vectors", angle);
// angleImg.show();
final ImagePlus quiverImg = new ImagePlus("Quiver Plot of Distortion Field", magnitude);
quiverImg.show();
quiverImg.getCanvas().setDisplayList(quiverField, Color.green, null);
quiverImg.updateAndDraw();
// GeneralPath gridOrig = new GeneralPath();
// drawGrid(gridOrig, gridOrigVert, countVert, height);
// drawGrid(gridOrig, gridOrigHor, countHorWhole, width);
// ImagePlus gridImgOrig = new ImagePlus("Distortion Grid", empty);
// gridImgOrig.show();
// gridImgOrig.getCanvas().setDisplayList(gridOrig, Color.green, null );
// gridImgOrig.updateAndDraw();
final GeneralPath gridTrans = new GeneralPath();
drawGrid(gridTrans, gridTransVert, countVert, height);
drawGrid(gridTrans, gridTransHor, countHorWhole, width);
final ImagePlus gridImgTrans = new ImagePlus("Distortion Grid", empty);
gridImgTrans.show();
gridImgTrans.getCanvas().setDisplayList(gridTrans, Color.green, null);
gridImgTrans.updateAndDraw();
// new FileSaver(quiverImg.getCanvas().imp).saveAsTiff("QuiverCanvas.tif");
new FileSaver(quiverImg).saveAsTiff("QuiverImPs.tif");
System.out.println("FINISHED");
}
Aggregations