use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.
the class FilePathRepair method fixStack.
private static int fixStack(final PathTableModel data, final Set<Patch> fixed, final Collection<Patch> slices, final String wrong_path, final String new_path, final boolean update_mipmaps) {
int n_fixed = 0;
Dimension dim = null;
Loader loader = null;
for (final Patch ps : slices) {
if (fixed.contains(ps))
continue;
final String slicepath = ps.getFilePath();
final int isl = slicepath.lastIndexOf("-----#slice=");
if (-1 == isl) {
Utils.log2("Not a stack path: " + slicepath);
// someone linked an image...
continue;
}
// same: // ps.getImageFilePath();
final String ps_path = slicepath.substring(0, isl);
if (!ps_path.substring(0, isl).equals(wrong_path)) {
Utils.log2("Not the same stack path:\n i=" + ps_path + "\n ref=" + wrong_path);
// not the same stack!
continue;
}
if (null == dim) {
loader = ps.getProject().getLoader();
loader.releaseToFit(Math.max(Loader.MIN_FREE_BYTES, ps.getOWidth() * ps.getOHeight() * 10));
dim = loader.getDimensions(new_path);
if (null == dim) {
// preserving backslashes
Utils.log(new StringBuilder("ERROR: could not open image at ").append(new_path).toString());
return n_fixed;
}
// Check dimensions
if (dim.width != ps.getOWidth() || dim.height != ps.getOHeight()) {
Utils.log("ERROR different o_width,o_height for patch " + ps + "\n at new path " + new_path + "\nold o_width,o_height: " + ps.getOWidth() + "," + ps.getOHeight() + "\nnew o_width,o_height: " + dim.width + "," + dim.height);
return n_fixed;
}
}
// flag as good
fixed.add(ps);
loader.removeFromUnloadable(ps);
// Assign new image path with slice info appended
loader.addedPatchFrom(new_path + slicepath.substring(isl), ps);
// submit job to regenerate mipmaps in the background
if (update_mipmaps)
loader.regenerateMipMaps(ps);
//
data.remove(ps);
n_fixed++;
}
return n_fixed;
}
use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.
the class PatchStack method resetNonActive.
/**
* Reset temporary changes such as from dragging B&C sliders and so on, in the current slice (the current Patch).
*/
public void resetNonActive() {
Utils.log2("PatchStack: calling reset");
// remake the awt for the patch, flush the previous awt
Loader loader = patch[currentSlice - 1].getProject().getLoader();
for (int i = 0; i < patch.length; i++) {
if (currentSlice - 1 == i || !called[i])
continue;
called[i] = false;
ImagePlus imp = loader.fetchImagePlus(patch[i]);
ImageProcessor ip = imp.getProcessor();
switch(// as in ij.plugin.frame.ContrastAdjuster.reset(ImagePlus, ImageProcessor)
imp.getType()) {
case ImagePlus.COLOR_RGB:
ip.reset();
break;
case ImagePlus.GRAY16:
case ImagePlus.GRAY32:
ip.resetMinAndMax();
break;
}
patch[i].setMinAndMax(ip.getMin(), ip.getMax());
patch[i].getProject().getLoader().decacheAWT(patch[i].getId());
Display.repaint(patch[i].getLayer(), patch[i], null, 0, true);
}
}
use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.
the class PatchStack method setProcessor.
public void setProcessor(String title, ImageProcessor ip) {
// so not applied to stacks
if (1 != patch.length)
return;
Loader loader = patch[currentSlice - 1].getProject().getLoader();
ImagePlus imp = loader.fetchImagePlus(patch[currentSlice - 1]);
if (ip.getWidth() != imp.getWidth() || ip.getHeight() != imp.getHeight())
throw new IllegalArgumentException("PatchStack: ip wrong size");
// null means don't touch title
imp.setProcessor(null, ip);
patch[currentSlice - 1].updateInDatabase("tiff_working");
// loader.vacuum();
// repainting elsewhere
}
use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.
the class PatchStack method saveImages.
/**
* Store working copies and remake the awts and repaint.
*/
public void saveImages() {
Utils.log2("PatchStack: calling saveImages");
if (!this.changes) {
Utils.log2("PatchStack.saveImages: nothing changed.");
return;
}
Loader loader = patch[currentSlice - 1].getProject().getLoader();
Utils.showProgress(0);
for (int i = 0; i < patch.length; i++) {
ImagePlus imp = loader.fetchImagePlus(patch[i]);
Utils.log2("PatchStack.saveImages: patch imp " + i + " has the imp.changes=" + imp.changes + " and the called[i]=" + called[i]);
if (imp.changes || called[i]) {
// may be doing it twice, check TODO
patch[i].updateInDatabase("tiff_working");
/*
patch[i].createImage(); //flushes the old awt, and creates the new one, and stores it in the cache.
*/
// just flush away all dependent images, will be recreated when needed on repaint
patch[i].getProject().getLoader().decache(imp);
Display.repaint(patch[i].getLayer(), patch[i], 0);
// reset
imp.changes = false;
called[i] = false;
}
Utils.showProgress((i + 1.0) / patch.length);
}
this.changes = false;
// patch[0].getProject().getLoader().vacuum();
Utils.showProgress(1);
}
use of ini.trakem2.display.Patch in project TrakEM2 by trakem2.
the class StitchingTEM method montageWithPhaseCorrelation.
/**
* Perform montage based on phase correlation
* @param col collection of patches
* @param param phase correlation parameters
*/
public static void montageWithPhaseCorrelation(final Collection<Patch> col, final PhaseCorrelationParam param) {
if (null == col || col.size() < 1)
return;
final ArrayList<Patch> al = new ArrayList<Patch>(col);
final ArrayList<AbstractAffineTile2D<?>> tiles = new ArrayList<AbstractAffineTile2D<?>>();
final ArrayList<AbstractAffineTile2D<?>> fixed_tiles = new ArrayList<AbstractAffineTile2D<?>>();
for (final Patch p : al) {
// Pre-check: just a warning
final int aff_type = p.getAffineTransform().getType();
switch(p.getAffineTransform().getType()) {
case AffineTransform.TYPE_IDENTITY:
case AffineTransform.TYPE_TRANSLATION:
// ok
break;
default:
Utils.log2("WARNING: patch with a non-translation transform: " + p);
break;
}
// create tiles
final TranslationTile2D tile = new TranslationTile2D(new TranslationModel2D(), p);
tiles.add(tile);
if (p.isLocked2()) {
Utils.log("Added fixed (locked) tile " + p);
fixed_tiles.add(tile);
}
}
// Get acceptable values
double cc_scale = param.cc_scale;
if (cc_scale < 0 || cc_scale > 1) {
Utils.log("Unacceptable cc_scale of " + param.cc_scale + ". Using 1 instead.");
cc_scale = 1;
}
float overlap = param.overlap;
if (overlap < 0 || overlap > 1) {
Utils.log("Unacceptable overlap of " + param.overlap + ". Using 1 instead.");
overlap = 1;
}
for (int i = 0; i < al.size(); i++) {
final Patch p1 = al.get(i);
final Rectangle r1 = p1.getBoundingBox();
// find overlapping, add as connections
for (int j = i + 1; j < al.size(); j++) {
if (Thread.currentThread().isInterrupted())
return;
final Patch p2 = al.get(j);
final Rectangle r2 = p2.getBoundingBox();
if (r1.intersects(r2)) {
// Skip if it's a diagonal overlap
final int dx = Math.abs(r1.x - r2.x);
final int dy = Math.abs(r1.y - r2.y);
if (dx > r1.width / 2 && dy > r1.height / 2) {
// skip diagonal match
Utils.log2("Skipping diagonal overlap between " + p1 + " and " + p2);
continue;
}
p1.getProject().getLoader().releaseToFit((long) (p1.getWidth() * p1.getHeight() * 25));
final double[] R;
if (1 == overlap) {
R = correlate(p1, p2, overlap, cc_scale, TOP_BOTTOM, 0, 0, param.min_R);
if (SUCCESS == R[2]) {
addMatches(tiles.get(i), tiles.get(j), R[0], R[1]);
}
} else {
switch(getClosestOverlapLocation(p1, p2)) {
case // p1 overlaps p2 from the left
0:
R = correlate(p1, p2, overlap, cc_scale, LEFT_RIGHT, 0, 0, param.min_R);
if (SUCCESS == R[2]) {
addMatches(tiles.get(i), tiles.get(j), R[0], R[1]);
}
break;
case // p1 overlaps p2 from the top
1:
R = correlate(p1, p2, overlap, cc_scale, TOP_BOTTOM, 0, 0, param.min_R);
if (SUCCESS == R[2]) {
addMatches(tiles.get(i), tiles.get(j), R[0], R[1]);
}
break;
case // p1 overlaps p2 from the right
2:
R = correlate(p2, p1, overlap, cc_scale, LEFT_RIGHT, 0, 0, param.min_R);
if (SUCCESS == R[2]) {
addMatches(tiles.get(j), tiles.get(i), R[0], R[1]);
}
break;
case // p1 overlaps p2 from the bottom
3:
R = correlate(p2, p1, overlap, cc_scale, TOP_BOTTOM, 0, 0, param.min_R);
if (SUCCESS == R[2]) {
addMatches(tiles.get(j), tiles.get(i), R[0], R[1]);
}
break;
default:
Utils.log("Unknown overlap direction!");
continue;
}
}
}
}
}
if (param.remove_disconnected || param.hide_disconnected) {
for (final Iterator<AbstractAffineTile2D<?>> it = tiles.iterator(); it.hasNext(); ) {
final AbstractAffineTile2D<?> t = it.next();
if (null != t.getMatches() && t.getMatches().isEmpty()) {
if (param.hide_disconnected)
t.getPatch().setVisible(false);
else if (param.remove_disconnected)
t.getPatch().remove(false);
it.remove();
}
}
}
// Optimize tile configuration by removing bad matches
optimizeTileConfiguration(tiles, fixed_tiles, param);
for (final AbstractAffineTile2D<?> t : tiles) t.getPatch().setAffineTransform(t.getModel().createAffine());
try {
Display.repaint(al.get(0).getLayer());
} catch (final Exception e) {
}
}
Aggregations