Search in sources :

Example 51 with Displayable

use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.

the class TemplateTree method renameType.

/**
 * Rename a TemplateThing type from @param old_name to @param new_name.
 *  If such a new_name already exists, the renaming will not occur and returns false.
 */
public boolean renameType(final String old_name, String new_name) {
    // to lower case!
    new_name = new_name.toLowerCase();
    Project project = root.getProject();
    if (new_name.equals(old_name)) {
        return true;
    } else if (project.typeExists(new_name)) {
        Utils.logAll("Type '" + new_name + "' exists already!");
        return false;
    }
    // process name change in all TemplateThing instances that have it
    ArrayList<TemplateThing> al = root.collectAllChildren(new ArrayList<TemplateThing>());
    al.add(root);
    for (final TemplateThing tet : al) {
        // Utils.log("\tchecking " + tet.getType() + " " + tet.getId());
        if (tet.getType().equals(old_name))
            tet.rename(new_name);
    }
    // and update the ProjectThing objects in the tree and its dependant Displayable objects in the open Displays
    project.getRootProjectThing().updateType(new_name, old_name);
    // tell the project about it
    project.updateTypeName(old_name, new_name);
    // repaint both trees (will update the type names)
    updateUILater();
    project.getProjectTree().updateUILater();
    return true;
}
Also used : Project(ini.trakem2.Project)

Example 52 with Displayable

use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.

the class Search method createCoordinate.

private Coordinate<Displayable> createCoordinate(final Displayable d) {
    Rectangle r = d.getBoundingBox();
    Layer la = d instanceof ZDisplayable ? ((ZDisplayable) d).getFirstLayer() : d.getLayer();
    if (null == la) {
        Display display = Display.getFront(d.getProject());
        if (null == display)
            la = d.getProject().getRootLayerSet().getLayer(0);
        else
            la = display.getLayer();
    }
    return new Coordinate<Displayable>(r.x + r.width / 2, r.y + r.height / 2, la, d);
}
Also used : ZDisplayable(ini.trakem2.display.ZDisplayable) Coordinate(ini.trakem2.display.Coordinate) Rectangle(java.awt.Rectangle) Layer(ini.trakem2.display.Layer) Display(ini.trakem2.display.Display)

Example 53 with Displayable

use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.

the class Project method getParentTitle.

/**
 * Returns the title of the enclosing abstract node in the ProjectTree.
 */
public String getParentTitle(final Displayable d) {
    try {
        ProjectThing thing = findProjectThing(d);
        ProjectThing parent = (ProjectThing) thing.getParent();
        if (d instanceof Profile) {
            // skip the profile_list
            parent = (ProjectThing) parent.getParent();
        }
        if (null == parent)
            Utils.log2("null parent for " + d);
        if (null != parent && null == parent.getObject()) {
            Utils.log2("null ob for parent " + parent + " of " + d);
        }
        // the abstract thing should be enclosing a String object
        return parent.getObject().toString();
    } catch (Exception e) {
        IJError.print(e);
        return null;
    }
}
Also used : ProjectThing(ini.trakem2.tree.ProjectThing) Profile(ini.trakem2.display.Profile)

Example 54 with Displayable

use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.

the class AreaList method exportAsLabels.

/**
 * Export all given AreaLists as one per pixel value, what is called a "labels" file; a file dialog is offered to save the image as a tiff stack.
 */
public static void exportAsLabels(final List<Displayable> listToPaint, final ij.gui.Roi roi, final float scale, int first_layer, int last_layer, final boolean visible_only, final boolean to_file, final boolean as_amira_labels) {
    // survive everything:
    if (null == listToPaint || 0 == listToPaint.size()) {
        Utils.log("Null or empty list.");
        return;
    }
    if (scale < 0 || scale > 1) {
        Utils.log("Improper scale value. Must be 0 < scale <= 1");
        return;
    }
    // Select the subset to paint
    final ArrayList<AreaList> list = new ArrayList<AreaList>();
    for (final Displayable d : listToPaint) {
        if (visible_only && !d.isVisible())
            continue;
        if (d instanceof AreaList)
            list.add((AreaList) d);
    }
    Utils.log2("exportAsLabels: list.size() is " + list.size());
    // Current AmiraMeshEncoder supports ByteProcessor only: 256 labels max, including background at zero.
    if (as_amira_labels && list.size() > 255) {
        Utils.log("Saving ONLY first 255 AreaLists!\nDiscarded:");
        final StringBuilder sb = new StringBuilder();
        for (final Displayable d : list.subList(255, list.size())) {
            sb.append("    ").append(d.getProject().getShortMeaningfulTitle(d)).append('\n');
        }
        Utils.log(sb.toString());
        final ArrayList<AreaList> li = new ArrayList<AreaList>(list);
        list.clear();
        list.addAll(li.subList(0, 255));
    }
    String path = null;
    if (to_file) {
        final String ext = as_amira_labels ? ".am" : ".tif";
        final File f = Utils.chooseFile("labels", ext);
        if (null == f)
            return;
        path = f.getAbsolutePath().replace('\\', '/');
    }
    final LayerSet layer_set = list.get(0).getLayerSet();
    if (first_layer > last_layer) {
        final int tmp = first_layer;
        first_layer = last_layer;
        last_layer = tmp;
        if (first_layer < 0)
            first_layer = 0;
        if (last_layer >= layer_set.size())
            last_layer = layer_set.size() - 1;
    }
    // Create image according to roi and scale
    final int width, height;
    final Rectangle broi;
    if (null == roi) {
        broi = null;
        width = (int) (layer_set.getLayerWidth() * scale);
        height = (int) (layer_set.getLayerHeight() * scale);
    } else {
        broi = roi.getBounds();
        width = (int) (broi.width * scale);
        height = (int) (broi.height * scale);
    }
    // Compute highest label value, which affects of course the stack image type
    final TreeSet<Integer> label_values = new TreeSet<Integer>();
    for (final Displayable d : list) {
        final String label = d.getProperty("label");
        if (null != label)
            label_values.add(Integer.parseInt(label));
    }
    int lowest = 0, highest = 0;
    if (label_values.size() > 0) {
        lowest = label_values.first();
        highest = label_values.last();
    }
    final int n_non_labeled = list.size() - label_values.size();
    final int max_label_value = highest + n_non_labeled;
    int type_ = ImagePlus.GRAY8;
    if (max_label_value > 255) {
        type_ = ImagePlus.GRAY16;
        if (max_label_value > 65535) {
            type_ = ImagePlus.GRAY32;
        }
    }
    final int type = type_;
    final ImageStack stack = new ImageStack(width, height);
    final Calibration cal = layer_set.getCalibration();
    String amira_params = null;
    if (as_amira_labels) {
        final StringBuilder sb = new StringBuilder("CoordType \"uniform\"\nMaterials {\nExterior {\n Id 0,\nColor 0 0 0\n}\n");
        final float[] c = new float[3];
        int value = 0;
        for (final Displayable d : list) {
            // 0 is background
            value++;
            d.getColor().getRGBColorComponents(c);
            String s = d.getProject().getShortMeaningfulTitle(d);
            s = s.replace('-', '_').replaceAll(" #", " id");
            sb.append(Utils.makeValidIdentifier(s)).append(" {\n").append("Id ").append(value).append(",\n").append("Color ").append(c[0]).append(' ').append(c[1]).append(' ').append(c[2]).append("\n}\n");
        }
        sb.append("}\n");
        amira_params = sb.toString();
    }
    final float len = last_layer - first_layer + 1;
    // Assign labels
    final HashMap<AreaList, Integer> labels = new HashMap<AreaList, Integer>();
    for (final AreaList d : list) {
        final String slabel = d.getProperty("label");
        int label;
        if (null != slabel) {
            label = Integer.parseInt(slabel);
        } else {
            // 0 is background
            label = (++highest);
        }
        labels.put(d, label);
    }
    final ExecutorService exec = Utils.newFixedThreadPool("labels");
    final Map<Integer, ImageProcessor> slices = Collections.synchronizedMap(new TreeMap<Integer, ImageProcessor>());
    final List<Future<?>> fus = new ArrayList<Future<?>>();
    final List<Layer> layers = layer_set.getLayers().subList(first_layer, last_layer + 1);
    for (int k = 0; k < layers.size(); k++) {
        final Layer la = layers.get(k);
        final int slice = k;
        fus.add(exec.submit(new Runnable() {

            @Override
            public void run() {
                Utils.showProgress(slice / len);
                final ImageProcessor ip;
                if (ImagePlus.GRAY8 == type) {
                    final BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
                    final Graphics2D g = bi.createGraphics();
                    for (final AreaList ali : list) {
                        final Area area = ali.getArea(la);
                        if (null == area || area.isEmpty())
                            continue;
                        // Transform: the scale and the roi
                        final AffineTransform aff = new AffineTransform();
                        /* 3 - To scale: */
                        if (1 != scale)
                            aff.scale(scale, scale);
                        /* 2 - To roi coordinates: */
                        if (null != broi)
                            aff.translate(-broi.x, -broi.y);
                        /* 1 - To world coordinates: */
                        aff.concatenate(ali.at);
                        g.setTransform(aff);
                        final int label = labels.get(ali);
                        g.setColor(new Color(label, label, label));
                        g.fill(area);
                    }
                    g.dispose();
                    ip = new ByteProcessor(bi);
                    bi.flush();
                } else if (ImagePlus.GRAY16 == type) {
                    final USHORTPaint paint = new USHORTPaint((short) 0);
                    final BufferedImage bi = new BufferedImage(paint.getComponentColorModel(), paint.getComponentColorModel().createCompatibleWritableRaster(width, height), false, null);
                    final Graphics2D g = bi.createGraphics();
                    // final ColorSpace ugray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
                    int painted = 0;
                    for (final AreaList ali : list) {
                        final Area area = ali.getArea(la);
                        if (null == area || area.isEmpty())
                            continue;
                        // Transform: the scale and the roi
                        final AffineTransform aff = new AffineTransform();
                        /* 3 - To scale: */
                        if (1 != scale)
                            aff.scale(scale, scale);
                        /* 2 - To roi coordinates: */
                        if (null != broi)
                            aff.translate(-broi.x, -broi.y);
                        /* 1 - To world coordinates: */
                        aff.concatenate(ali.at);
                        // Fill
                        g.setTransform(aff);
                        // The color doesn't work: paints in a stretched 8-bit mode
                        // g.setColor(new Color(ugray, new float[]{((float)labels.get(d)) / range}, 1));
                        Utils.log2("value: " + labels.get(ali).shortValue());
                        paint.setValue(labels.get(ali).shortValue());
                        g.setPaint(paint);
                        // .createTransformedArea(aff));
                        g.fill(area);
                        painted += 1;
                    }
                    g.dispose();
                    ip = new ShortProcessor(bi);
                    bi.flush();
                    Utils.log2("painted: " + painted);
                } else {
                    // Option 1: could use the same as above, but shifted by 65536, so that 65537 is 1, 65538 is 2, etc.
                    // and keep doing it until no more need to be shifted.
                    // The PROBLEM: cannot keep the order without complicated gymnastics to remember
                    // which label in which image has to be merged to the final image, which prevent
                    // a simple one-pass blitter.
                    // 
                    // Option 2: paint each arealist, extract the image, use it as a mask for filling:
                    final FloatProcessor fp = new FloatProcessor(width, height);
                    final float[] fpix = (float[]) fp.getPixels();
                    ip = fp;
                    final BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
                    final Graphics2D gbi = bi.createGraphics();
                    for (final AreaList ali : list) {
                        final Area area = ali.getArea(la);
                        if (null == area || area.isEmpty()) {
                            continue;
                        }
                        // Transform: the scale and the roi
                        // reverse order of transformations:
                        final AffineTransform aff = new AffineTransform();
                        /* 3 - To scale: */
                        if (1 != scale)
                            aff.scale(scale, scale);
                        /* 2 - To ROI coordinates: */
                        if (null != broi)
                            aff.translate(-broi.x, -broi.y);
                        /* 1 - To world coordinates: */
                        aff.concatenate(ali.at);
                        final Area s = area.createTransformedArea(aff);
                        final Rectangle sBounds = s.getBounds();
                        // Need to paint at all?
                        if (0 == sBounds.width || 0 == sBounds.height || !sBounds.intersects(0, 0, width, height))
                            continue;
                        // Paint shape
                        gbi.setColor(Color.white);
                        gbi.fill(s);
                        // Read out painted region
                        final int x0 = Math.max(0, sBounds.x);
                        final int y0 = Math.max(0, sBounds.y);
                        final int xN = Math.min(width, sBounds.x + sBounds.width);
                        final int yN = Math.min(height, sBounds.y + sBounds.height);
                        // Get the array
                        final byte[] bpix = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
                        final float value = labels.get(ali);
                        // For every non-black pixel, set a 'value' pixel in the FloatProcessor
                        for (int y = y0; y < yN; ++y) {
                            for (int x = x0; x < xN; ++x) {
                                final int pos = y * width + x;
                                // black
                                if (0 == bpix[pos])
                                    continue;
                                fpix[pos] = value;
                            }
                        }
                        // Clear image region
                        gbi.setColor(Color.black);
                        gbi.fill(s);
                    }
                    gbi.dispose();
                    bi.flush();
                }
                slices.put(slice, ip);
            }
        }));
    }
    Utils.wait(fus);
    exec.shutdownNow();
    for (final Map.Entry<Integer, ImageProcessor> e : slices.entrySet()) {
        final Layer la = layers.get(e.getKey());
        stack.addSlice(la.getZ() * cal.pixelWidth + "", e.getValue());
        if (ImagePlus.GRAY8 != type) {
            e.getValue().setMinAndMax(lowest, highest);
        }
    }
    Utils.showProgress(1);
    // Save via file dialog:
    final ImagePlus imp = new ImagePlus("Labels", stack);
    if (as_amira_labels)
        imp.setProperty("Info", amira_params);
    imp.setCalibration(layer_set.getCalibrationCopy());
    if (to_file) {
        if (as_amira_labels) {
            final AmiraMeshEncoder ame = new AmiraMeshEncoder(path);
            if (!ame.open()) {
                Utils.log("Could not write to file " + path);
                return;
            }
            if (!ame.write(imp)) {
                Utils.log("Error in writing Amira file!");
                return;
            }
        } else {
            new FileSaver(imp).saveAsTiff(path);
        }
    } else
        imp.show();
}
Also used : ByteProcessor(ij.process.ByteProcessor) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Rectangle(java.awt.Rectangle) BufferedImage(java.awt.image.BufferedImage) ImageProcessor(ij.process.ImageProcessor) USHORTPaint(ini.trakem2.display.paint.USHORTPaint) FileSaver(ij.io.FileSaver) TreeSet(java.util.TreeSet) ImageStack(ij.ImageStack) FloatProcessor(ij.process.FloatProcessor) Color(java.awt.Color) Calibration(ij.measure.Calibration) ImagePlus(ij.ImagePlus) Point(java.awt.Point) USHORTPaint(ini.trakem2.display.paint.USHORTPaint) Graphics2D(java.awt.Graphics2D) ShortProcessor(ij.process.ShortProcessor) Area(java.awt.geom.Area) ExecutorService(java.util.concurrent.ExecutorService) AmiraMeshEncoder(amira.AmiraMeshEncoder) Future(java.util.concurrent.Future) AffineTransform(java.awt.geom.AffineTransform) File(java.io.File) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 55 with Displayable

use of ini.trakem2.display.Displayable in project TrakEM2 by trakem2.

the class Graph method extractAndShowGraph.

/**
 * Shows a dialog to pick which classes is one interested in.
 */
public static final void extractAndShowGraph(final LayerSet ls) {
    GenericDialog gd = new GenericDialog("Graph elements");
    Class<Displayable>[] c = new Class[] { AreaList.class, AreaTree.class, Ball.class, Connector.class, Patch.class, Pipe.class, Polyline.class, Profile.class, DLabel.class, Treeline.class };
    String[] types = new String[] { "AreaList", "AreaTree", "Ball", "Connector", "Image", "Pipe", "Polyline", "Profile", "Text", "Treeline" };
    boolean[] states = new boolean[] { true, true, false, false, false, false, true, true, false, true };
    assert (c.length == types.length && types.length == states.length);
    for (int i = 0; i < c.length; i++) {
        if (ZDisplayable.class.isAssignableFrom(c[i])) {
            if (!ls.contains(c[i]))
                states[i] = false;
        } else if (!ls.containsDisplayable(c[i]))
            states[i] = false;
    }
    gd.addCheckboxGroup(types.length, 1, types, states, new String[] { "Include only:" });
    gd.showDialog();
    if (gd.wasCanceled())
        return;
    HashSet<Class<Displayable>> only = new HashSet<Class<Displayable>>();
    for (int i = 0; i < types.length; i++) {
        if (gd.getNextBoolean())
            only.add(c[i]);
    }
    Graph.extractAndShowGraph(ls, only);
}
Also used : AreaTree(ini.trakem2.display.AreaTree) Ball(ini.trakem2.display.Ball) Connector(ini.trakem2.display.Connector) Displayable(ini.trakem2.display.Displayable) ZDisplayable(ini.trakem2.display.ZDisplayable) Pipe(ini.trakem2.display.Pipe) AreaList(ini.trakem2.display.AreaList) Profile(ini.trakem2.display.Profile) Point(java.awt.Point) DLabel(ini.trakem2.display.DLabel) Treeline(ini.trakem2.display.Treeline) GenericDialog(ij.gui.GenericDialog) Polyline(ini.trakem2.display.Polyline) Patch(ini.trakem2.display.Patch) HashSet(java.util.HashSet)

Aggregations

Displayable (ini.trakem2.display.Displayable)50 ArrayList (java.util.ArrayList)36 ZDisplayable (ini.trakem2.display.ZDisplayable)29 Patch (ini.trakem2.display.Patch)27 HashMap (java.util.HashMap)24 HashSet (java.util.HashSet)23 Layer (ini.trakem2.display.Layer)21 Rectangle (java.awt.Rectangle)17 ProjectThing (ini.trakem2.tree.ProjectThing)15 DBObject (ini.trakem2.persistence.DBObject)14 ImagePlus (ij.ImagePlus)13 LayerSet (ini.trakem2.display.LayerSet)12 Point (java.awt.Point)11 AffineTransform (java.awt.geom.AffineTransform)11 Map (java.util.Map)11 GenericDialog (ij.gui.GenericDialog)10 Collection (java.util.Collection)10 Worker (ini.trakem2.utils.Worker)9 Area (java.awt.geom.Area)9 TreeMap (java.util.TreeMap)9