use of mpicbg.trakem2.transform.AffineModel2D in project TrakEM2 by trakem2.
the class Util method applyLayerTransformToPatch.
public static final void applyLayerTransformToPatch(final Patch patch, final CoordinateTransform ct) throws Exception {
final Rectangle pbox = patch.getCoordinateTransformBoundingBox();
final AffineTransform pat = new AffineTransform();
pat.translate(-pbox.x, -pbox.y);
pat.preConcatenate(patch.getAffineTransform());
final AffineModel2D toWorld = new AffineModel2D();
toWorld.set(pat);
final CoordinateTransformList<CoordinateTransform> ctl = new CoordinateTransformList<CoordinateTransform>();
ctl.add(toWorld);
ctl.add(ct);
ctl.add(toWorld.createInverse());
patch.appendCoordinateTransform(ctl);
}
use of mpicbg.trakem2.transform.AffineModel2D in project TrakEM2 by trakem2.
the class ExportARGB method makeFlatImageARGBFromOriginals.
/**
* Limited to 2GB arrays for the requested image.
*
* @param patches
* @param roi
* @param backgroundValue
* @param scale
* @return
*/
public static final Pair<ColorProcessor, ByteProcessor> makeFlatImageARGBFromOriginals(final List<Patch> patches, final Rectangle roi, final double backgroundValue, final double scale) {
final ColorProcessor target = new ColorProcessor((int) (roi.width * scale), (int) (roi.height * scale));
target.setInterpolationMethod(ImageProcessor.BILINEAR);
final ByteProcessor targetMask = new ByteProcessor(target.getWidth(), target.getHeight());
targetMask.setInterpolationMethod(ImageProcessor.NEAREST_NEIGHBOR);
for (final Patch patch : patches) {
final Patch.PatchImage pai = patch.createTransformedImage();
final ColorProcessor fp = (ColorProcessor) pai.target.convertToRGB();
final ByteProcessor alpha;
System.out.println("IMAGE:" + patch.getTitle());
System.out.println("mask: " + pai.mask);
System.out.println("outside: " + pai.outside);
if (null == pai.mask) {
if (null == pai.outside) {
alpha = new ByteProcessor(fp.getWidth(), fp.getHeight());
// fully opaque
Arrays.fill((byte[]) alpha.getPixels(), (byte) 255);
} else {
alpha = pai.outside;
}
} else {
alpha = pai.mask;
}
// The affine to apply
final AffineTransform atc = new AffineTransform();
atc.scale(scale, scale);
atc.translate(-roi.x, -roi.y);
final AffineTransform at = new AffineTransform();
at.preConcatenate(atc);
at.concatenate(patch.getAffineTransform());
final AffineModel2D aff = new AffineModel2D();
aff.set(at);
final CoordinateTransformMesh mesh = new CoordinateTransformMesh(aff, patch.getMeshResolution(), fp.getWidth(), fp.getHeight());
final TransformMeshMappingWithMasks<CoordinateTransformMesh> mapping = new TransformMeshMappingWithMasks<CoordinateTransformMesh>(mesh);
fp.setInterpolationMethod(ImageProcessor.BILINEAR);
// no interpolation
alpha.setInterpolationMethod(ImageProcessor.NEAREST_NEIGHBOR);
mapping.map(fp, alpha, target, targetMask);
}
return new Pair<ColorProcessor, ByteProcessor>(target, targetMask);
}
use of mpicbg.trakem2.transform.AffineModel2D in project TrakEM2 by trakem2.
the class NonLinearTransformMode method applyToPatch.
private final Future<Boolean> applyToPatch(final Patch patch) throws Exception {
final Rectangle pbox = patch.getCoordinateTransformBoundingBox();
final AffineTransform pat = new AffineTransform();
pat.translate(-pbox.x, -pbox.y);
pat.preConcatenate(patch.getAffineTransform());
final AffineModel2D toWorld = new AffineModel2D();
toWorld.set(pat);
final CoordinateTransform mlst = createCT();
final CoordinateTransformList<CoordinateTransform> ctl = new CoordinateTransformList<CoordinateTransform>();
ctl.add(toWorld);
ctl.add(mlst);
ctl.add(toWorld.createInverse());
patch.appendCoordinateTransform(ctl);
return patch.updateMipMaps();
}
use of mpicbg.trakem2.transform.AffineModel2D in project TrakEM2 by trakem2.
the class Patch method makeFlatImage.
/**
* Creates an ImageProcessor of the specified type.
* @param type Any of ImagePlus.GRAY_8, GRAY_16, GRAY_32 or COLOR_RGB.
* @param srcRect the box in world coordinates to make an image out of.
* @param scale may be up to 1.0.
* @param patches The list of patches to paint. The first gets painted first (at the bottom).
* @param background The color with which to paint the outsides where no image paints into.
* @param setMinAndMax defines whether the min and max of each Patch is set before pasting the Patch.
*
* For exporting while blending the display ranges (min,max) and respecting alpha masks, see {@link ExportUnsignedShort}.
*/
public static ImageProcessor makeFlatImage(final int type, final Layer layer, final Rectangle srcRect, final double scale, final Collection<Patch> patches, final Color background, final boolean setMinAndMax) {
final ImageProcessor ip;
final int W, H;
if (scale < 1) {
W = (int) (srcRect.width * scale);
H = (int) (srcRect.height * scale);
} else {
W = srcRect.width;
H = srcRect.height;
}
switch(type) {
case ImagePlus.GRAY8:
ip = new ByteProcessor(W, H);
break;
case ImagePlus.GRAY16:
ip = new ShortProcessor(W, H);
break;
case ImagePlus.GRAY32:
ip = new FloatProcessor(W, H);
break;
case ImagePlus.COLOR_RGB:
ip = new ColorProcessor(W, H);
break;
default:
Utils.logAll("Cannot create an image of type " + type + ".\nSupported types: 8-bit, 16-bit, 32-bit and RGB.");
return null;
}
// Fill with background
if (null != background && Color.black != background) {
ip.setColor(background);
ip.fill();
}
AffineModel2D sc = null;
if (scale < 1.0) {
sc = new AffineModel2D();
sc.set(scale, 0, 0, scale, 0, 0);
}
for (final Patch p : patches) {
// TODO patches seem to come in in inverse order---find out why
// A list to represent all the transformations that the Patch image has to go through to reach the scaled srcRect image
final CoordinateTransformList<CoordinateTransform> list = new CoordinateTransformList<CoordinateTransform>();
final AffineTransform at = new AffineTransform();
at.translate(-srcRect.x, -srcRect.y);
at.concatenate(p.getAffineTransform());
// 1. The coordinate tranform of the Patch, if any
if (p.hasCoordinateTransform()) {
final CoordinateTransform ct = p.getCoordinateTransform();
list.add(ct);
// Remove the translation in the patch_affine that the ct added to it
final Rectangle box = Patch.getCoordinateTransformBoundingBox(p, ct);
at.translate(-box.x, -box.y);
}
// 2. The affine transform of the Patch
final AffineModel2D patch_affine = new AffineModel2D();
patch_affine.set(at);
list.add(patch_affine);
// 3. The desired scaling
if (null != sc)
patch_affine.preConcatenate(sc);
final CoordinateTransformMesh mesh = new CoordinateTransformMesh(list, p.meshResolution, p.getOWidth(), p.getOHeight());
final mpicbg.ij.TransformMeshMapping<CoordinateTransformMesh> mapping = new mpicbg.ij.TransformMeshMapping<CoordinateTransformMesh>(mesh);
// 4. Convert the patch to the required type
ImageProcessor pi = p.getImageProcessor();
if (setMinAndMax) {
pi = pi.duplicate();
pi.setMinAndMax(p.min, p.max);
}
switch(type) {
case ImagePlus.GRAY8:
pi = pi.convertToByte(true);
break;
case ImagePlus.GRAY16:
pi = pi.convertToShort(true);
break;
case ImagePlus.GRAY32:
pi = pi.convertToFloat();
break;
default:
// ImagePlus.COLOR_RGB and COLOR_256
pi = pi.convertToRGB();
break;
}
/* TODO for taking into account independent min/max setting for each patch,
* we will need a mapping with an `intensity transfer function' to be implemented.
* --> EXISTS already as mpicbg/trakem2/transform/ExportUnsignedShort.java
*/
mapping.mapInterpolated(pi, ip);
}
return ip;
}
use of mpicbg.trakem2.transform.AffineModel2D in project TrakEM2 by trakem2.
the class Patch method keyPressed.
@Override
public void keyPressed(final KeyEvent ke) {
final Object source = ke.getSource();
if (!(source instanceof DisplayCanvas))
return;
final DisplayCanvas dc = (DisplayCanvas) source;
final Roi roi = dc.getFakeImagePlus().getRoi();
final int mod = ke.getModifiers();
switch(ke.getKeyCode()) {
case KeyEvent.VK_C:
// Ignoring masks: outside is already black, and ImageJ cannot handle alpha masks.
if (0 == (mod ^ (Event.SHIFT_MASK | Event.ALT_MASK))) {
// Place the source image, untransformed, into clipboard:
final ImagePlus imp = getImagePlus();
if (null != imp)
imp.copy(false);
} else if (0 == mod || (0 == (mod ^ Event.SHIFT_MASK))) {
CoordinateTransformList<CoordinateTransform> list = null;
if (hasCoordinateTransform()) {
list = new CoordinateTransformList<CoordinateTransform>();
list.add(getCoordinateTransform());
}
if (0 == mod) {
// SHIFT is not down
final AffineModel2D am = new AffineModel2D();
am.set(this.at);
if (null == list)
list = new CoordinateTransformList<CoordinateTransform>();
list.add(am);
}
ImageProcessor ip;
if (null != list) {
final TransformMesh mesh = new TransformMesh(list, meshResolution, o_width, o_height);
final TransformMeshMapping mapping = new TransformMeshMapping(mesh);
ip = mapping.createMappedImageInterpolated(getImageProcessor());
} else {
ip = getImageProcessor();
}
new ImagePlus(this.title, ip).copy(false);
}
ke.consume();
break;
case KeyEvent.VK_F:
// fill mask with current ROI using
if (null != roi && M.isAreaROI(roi)) {
Bureaucrat.createAndStart(new Worker.Task("Filling image mask") {
@Override
public void exec() {
getLayerSet().addDataEditStep(Patch.this);
if (0 == mod) {
addAlphaMask(roi, ProjectToolbar.getForegroundColorValue());
} else if (0 == (mod ^ Event.SHIFT_MASK)) {
// shift is down: fill outside
try {
final Area localRoi = M.areaInInts(M.getArea(roi)).createTransformedArea(at.createInverse());
final Area invLocalRoi = new Area(new Rectangle(0, 0, getOWidth(), getOHeight()));
invLocalRoi.subtract(localRoi);
addAlphaMaskLocal(invLocalRoi, ProjectToolbar.getForegroundColorValue());
} catch (final NoninvertibleTransformException e) {
IJError.print(e);
return;
}
}
getLayerSet().addDataEditStep(Patch.this);
// wait
try {
updateMipMaps().get();
} catch (final Throwable t) {
IJError.print(t);
}
Display.repaint();
}
}, project);
}
// capturing:
ke.consume();
break;
default:
super.keyPressed(ke);
break;
}
}
Aggregations