Search in sources :

Example 6 with Displayable

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

the class FilterEditor method GUI.

public static final void GUI(final Collection<Patch> patches, final Patch reference) {
    final ArrayList<FilterWrapper> filters = new ArrayList<FilterWrapper>();
    // Find out if all images have the exact same filters
    final StringBuilder sb = new StringBuilder();
    final Patch ref = (null == reference ? patches.iterator().next() : reference);
    final IFilter[] refFilters = ref.getFilters();
    if (null != refFilters) {
        // makes a copy of the IFilter
        for (final IFilter f : refFilters) filters.add(new FilterWrapper(f));
    }
    // 
    for (final Patch p : patches) {
        if (ref == p)
            continue;
        final IFilter[] fs = p.getFilters();
        // ok
        if (null == fs && null == refFilters)
            continue;
        if ((null != refFilters && null == fs) || (null == refFilters && null != fs) || (null != refFilters && null != fs && fs.length != refFilters.length)) {
            sb.append("WARNING: patch #" + p.getId() + " has a different number of filters than reference patch #" + ref.getId());
            continue;
        }
        // Compare each
        for (int i = 0; i < refFilters.length; ++i) {
            if (fs[i].getClass() != refFilters[i].getClass()) {
                sb.append("WARNING: patch #" + p.getId() + " has a different filters than reference patch #" + ref.getId());
                break;
            }
            // Does the filter have the same parameters?
            if (!filters.get(i).sameParameterValues(new FilterWrapper(fs[i]))) {
                sb.append("WARNING: patch #" + p.getId() + " has filter '" + fs[i].getClass().getSimpleName() + "' with different parameters than the reference patch #" + ref.getId());
            }
        }
    }
    if (sb.length() > 0) {
        final GenericDialog gd = new GenericDialog("WARNING", null == Display.getFront() ? IJ.getInstance() : Display.getFront().getFrame());
        gd.addMessage("Filters are not all the same for all images:");
        gd.addTextAreas(sb.toString(), null, 20, 30);
        final String[] s = new String[] { "Use the filters of the reference image", "Start from an empty list of filters" };
        gd.addChoice("Do:", s, s[0]);
        gd.showDialog();
        if (gd.wasCanceled())
            return;
        if (1 == gd.getNextChoiceIndex())
            filters.clear();
    }
    final TableChosenFilters tcf = new TableChosenFilters(filters);
    final TableParameters tp = new TableParameters(tcf);
    tcf.setupListener(tp);
    final TableAvailableFilters taf = new TableAvailableFilters(tcf);
    if (filters.size() > 0) {
        tcf.getSelectionModel().setSelectionInterval(0, 0);
    }
    final JFrame frame = new JFrame("Image filters");
    final JButton set = new JButton("Set");
    final JComboBox pulldown = new JComboBox(new String[] { "Selected images (" + patches.size() + ")", "All images in layer " + (ref.getLayer().getParent().indexOf(ref.getLayer()) + 1), "All images in layer range..." });
    final Component[] cs = new Component[] { set, pulldown, tcf, tp, taf };
    set.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(final ActionEvent e) {
            if (check(frame, filters)) {
                final ArrayList<Patch> ps = new ArrayList<Patch>();
                switch(pulldown.getSelectedIndex()) {
                    case 0:
                        ps.addAll(patches);
                        break;
                    case 1:
                        for (final Displayable d : ref.getLayer().getDisplayables(Patch.class)) {
                            ps.add((Patch) d);
                        }
                        break;
                    case 2:
                        final GenericDialog gd = new GenericDialog("Apply filters");
                        Utils.addLayerRangeChoices(ref.getLayer(), gd);
                        gd.addStringField("Image title matches:", "", 30);
                        gd.addCheckbox("Visible images only", true);
                        gd.showDialog();
                        if (gd.wasCanceled())
                            return;
                        final String regex = gd.getNextString();
                        final boolean visible_only = gd.getNextBoolean();
                        Pattern pattern = null;
                        if (0 != regex.length()) {
                            pattern = Pattern.compile(regex);
                        }
                        for (final Layer l : ref.getLayer().getParent().getLayers(gd.getNextChoiceIndex(), gd.getNextChoiceIndex())) {
                            for (final Displayable d : l.getDisplayables(Patch.class, visible_only)) {
                                if (null != pattern && !pattern.matcher(d.getTitle()).matches()) {
                                    continue;
                                }
                                ps.add((Patch) d);
                            }
                        }
                }
                apply(ps, filters, cs, false);
            }
        }
    });
    final JPanel buttons = new JPanel();
    final JLabel label = new JLabel("Push F1 for help");
    final GridBagConstraints c2 = new GridBagConstraints();
    final GridBagLayout gb2 = new GridBagLayout();
    buttons.setLayout(gb2);
    c2.anchor = GridBagConstraints.WEST;
    c2.gridx = 0;
    gb2.setConstraints(label, c2);
    buttons.add(label);
    c2.gridx = 1;
    c2.weightx = 1;
    final JPanel empty = new JPanel();
    gb2.setConstraints(empty, c2);
    buttons.add(empty);
    c2.gridx = 2;
    c2.weightx = 0;
    c2.anchor = GridBagConstraints.EAST;
    final JLabel a = new JLabel("Apply to:");
    gb2.setConstraints(a, c2);
    buttons.add(a);
    c2.gridx = 3;
    c2.insets = new Insets(4, 10, 4, 0);
    gb2.setConstraints(pulldown, c2);
    buttons.add(pulldown);
    c2.gridx = 4;
    gb2.setConstraints(set, c2);
    buttons.add(set);
    // 
    taf.setPreferredSize(new Dimension(350, 500));
    tcf.setPreferredSize(new Dimension(350, 250));
    tp.setPreferredSize(new Dimension(350, 250));
    // 
    final GridBagLayout gb = new GridBagLayout();
    final GridBagConstraints c = new GridBagConstraints();
    final JPanel all = new JPanel();
    all.setBackground(Color.white);
    all.setPreferredSize(new Dimension(700, 500));
    all.setLayout(gb);
    c.gridx = 0;
    c.gridy = 0;
    c.anchor = GridBagConstraints.NORTHWEST;
    c.fill = GridBagConstraints.BOTH;
    c.gridheight = 2;
    c.weightx = 0.5;
    final JScrollPane p1 = new JScrollPane(taf);
    p1.setPreferredSize(taf.getPreferredSize());
    gb.setConstraints(p1, c);
    all.add(p1);
    c.gridx = 1;
    c.gridy = 0;
    c.gridheight = 1;
    c.weighty = 0.7;
    final JScrollPane p2 = new JScrollPane(tcf);
    p2.setPreferredSize(tcf.getPreferredSize());
    gb.setConstraints(p2, c);
    all.add(p2);
    c.gridx = 1;
    c.gridy = 1;
    c.weighty = 0.3;
    final JScrollPane p3 = new JScrollPane(tp);
    p3.setPreferredSize(tp.getPreferredSize());
    gb.setConstraints(p3, c);
    all.add(p3);
    c.gridx = 0;
    c.gridy = 2;
    c.gridwidth = 2;
    c.weightx = 1;
    c.weighty = 0;
    gb.setConstraints(buttons, c);
    all.add(buttons);
    final KeyAdapter help = new KeyAdapter() {

        @Override
        public void keyPressed(final KeyEvent ke) {
            if (ke.getKeyCode() == KeyEvent.VK_F1) {
                final GenericDialog gd = new GenericDialog("Help :: image filters");
                gd.addMessage("In the table 'Available Filters':\n" + " - double-click a filter to add it to the table of 'Chosen Filters'\n \n" + "In the table 'Chosen Filters':\n" + " - double-click a filter to remove it.\n" + " - PAGE UP/DOWN keys move the filter up/down in the list.\n" + " - 'Delete' key removes the selected filter.\n \n" + "In the table of parameter names and values:\n" + " - double-click a value to edit it. Then push enter to set the new value.\n \n" + "What you need to know:\n" + " - filters are set and applied in order, so order matters.\n" + " - filters with parameters for which you entered a value of zero\nwill result in a warning message.\n" + " - when applying the filters, if you choose 'Selected images', these are the images\nthat were selected when the filter editor was opened.\n" + " - when applying the filters, if you want to filter for a regular expression pattern\nin the image name, use the 'All images in layer range...' option,\nwhere a range of one single layer is also possible.");
                gd.hideCancelButton();
                gd.setModal(false);
                gd.showDialog();
            }
        }
    };
    taf.addKeyListener(help);
    tcf.addKeyListener(help);
    tp.addKeyListener(help);
    all.addKeyListener(help);
    buttons.addKeyListener(help);
    empty.addKeyListener(help);
    a.addKeyListener(help);
    frame.getContentPane().add(all);
    frame.pack();
    frame.setVisible(true);
}
Also used : JPanel(javax.swing.JPanel) GridBagConstraints(java.awt.GridBagConstraints) Insets(java.awt.Insets) GridBagLayout(java.awt.GridBagLayout) ActionEvent(java.awt.event.ActionEvent) KeyAdapter(java.awt.event.KeyAdapter) ArrayList(java.util.ArrayList) JButton(javax.swing.JButton) KeyEvent(java.awt.event.KeyEvent) JFrame(javax.swing.JFrame) GenericDialog(ij.gui.GenericDialog) Component(java.awt.Component) JScrollPane(javax.swing.JScrollPane) Pattern(java.util.regex.Pattern) Displayable(ini.trakem2.display.Displayable) JComboBox(javax.swing.JComboBox) JLabel(javax.swing.JLabel) Dimension(java.awt.Dimension) Layer(ini.trakem2.display.Layer) ActionListener(java.awt.event.ActionListener) Patch(ini.trakem2.display.Patch)

Example 7 with Displayable

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

the class DefaultGraphicsSource method paintOnTop.

/**
 * Paints bounding boxes of selected objects as pink and active object as white.
 */
public void paintOnTop(final Graphics2D g, final Display display, final Rectangle srcRect, final double magnification) {
    if (ProjectToolbar.getToolId() >= ProjectToolbar.PENCIL) {
        // PENCIL == SPARE2
        return;
    }
    g.setColor(Color.pink);
    Displayable active = display.getActive();
    final Rectangle bbox = new Rectangle();
    for (final Displayable d : display.getSelection().getSelected()) {
        d.getBoundingBox(bbox);
        if (d == active) {
            g.setColor(Color.white);
            // g.drawPolygon(d.getPerimeter());
            g.drawRect(bbox.x, bbox.y, bbox.width, bbox.height);
            g.setColor(Color.pink);
        } else {
            // g.drawPolygon(d.getPerimeter());
            g.drawRect(bbox.x, bbox.y, bbox.width, bbox.height);
        }
    }
}
Also used : Displayable(ini.trakem2.display.Displayable) Rectangle(java.awt.Rectangle)

Example 8 with Displayable

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

the class AlignTask method createTransformPropertiesTable.

/**
 * Creates a map only for visible patches that intersect vdata.
 *  @param src_vdata represents the VectorData instances in original form, of the original project and layer set.
 *  @param tgt_vdata if not null, it must have the same size as src_data and their elements correspond one-to-one (as in, tgt element a clone of src element at the same index).
 *  @param lids_to_operate The id of the layers on which any operation will be done
 *  tgt_data enables transformVectorData to apply the transforms to copies of the src_vdata in another project.
 */
public static final ReferenceData createTransformPropertiesTable(final List<Displayable> src_vdata, final List<Displayable> tgt_vdata, final Set<Long> lids_to_operate) {
    if (src_vdata.isEmpty())
        return null;
    final Map<Long, Patch.TransformProperties> tp = new HashMap<Long, Patch.TransformProperties>();
    // A map of Displayable vs a map of Layer id vs list of Patch ids in that Layer that lay under the Patch, sorted by stack index
    final Map<Displayable, Map<Long, TreeMap<Integer, Long>>> underlying = new HashMap<Displayable, Map<Long, TreeMap<Integer, Long>>>();
    // The set of layers used
    final Set<Long> src_layer_lids_used = new HashSet<Long>();
    // Parallelize! This operation can be insanely expensive
    final int nproc = Runtime.getRuntime().availableProcessors();
    final ExecutorService exec = Utils.newFixedThreadPool(nproc, "AlignTask-createTransformPropertiesTable");
    final List<Future<?>> dtasks = new ArrayList<Future<?>>();
    final List<Future<?>> ltasks = new ArrayList<Future<?>>();
    final Thread current = Thread.currentThread();
    try {
        for (int i = src_vdata.size() - 1; i > -1; i--) {
            final Displayable src_d = src_vdata.get(i);
            // filter out
            if (!(src_d instanceof VectorData))
                continue;
            // use src_d if tgt_vdata is null
            final Displayable tgt_d = null == tgt_vdata ? src_d : tgt_vdata.get(i);
            // Some checking
            if (!(tgt_d instanceof VectorData)) {
                Utils.log("WARNING ignoring provided tgt_vdata " + tgt_d + " which is NOT a VectorData instance!");
                continue;
            }
            if (src_d.getClass() != tgt_d.getClass()) {
                Utils.log("WARNING src_d and tgt_d are instances of different classes:\n  src_d :: " + src_d + "\n  tgt_d :: " + tgt_d);
            }
            dtasks.add(exec.submit(new Runnable() {

                @SuppressWarnings({ "unchecked", "rawtypes" })
                @Override
                public void run() {
                    final Map<Long, TreeMap<Integer, Long>> under = new HashMap<Long, TreeMap<Integer, Long>>();
                    synchronized (underlying) {
                        underlying.put(tgt_d, under);
                    }
                    if (current.isInterrupted())
                        return;
                    // Iterate the layers in which this VectorData has any data AND which have to be transformed
                    for (final Long olid : src_d.getLayerIds()) {
                        final long lid = olid.longValue();
                        // layer with id 'lid' is not affected
                        if (!lids_to_operate.contains(lid))
                            continue;
                        final Layer la = src_d.getLayerSet().getLayer(lid);
                        final Area a = src_d.getAreaAt(la);
                        if (null == a || a.isEmpty()) {
                            // does not paint in the layer
                            continue;
                        }
                        // The list of patches that lay under VectorData d, sorted by their stack index in the layer
                        final TreeMap<Integer, Long> stacked_patch_ids = new TreeMap<Integer, Long>();
                        synchronized (under) {
                            under.put(lid, stacked_patch_ids);
                        }
                        final boolean[] layer_visited = new boolean[] { false };
                        // Iterate source patches
                        for (final Patch patch : (Collection<Patch>) (Collection) la.getDisplayables(Patch.class, a, true)) {
                            // pick visible patches only
                            if (current.isInterrupted())
                                return;
                            try {
                                ltasks.add(exec.submit(new Runnable() {

                                    @Override
                                    public void run() {
                                        if (current.isInterrupted())
                                            return;
                                        synchronized (patch) {
                                            Patch.TransformProperties props;
                                            synchronized (tp) {
                                                props = tp.get(patch.getId());
                                            }
                                            if (null == props) {
                                                props = patch.getTransformPropertiesCopy();
                                                // Cache the props
                                                synchronized (tp) {
                                                    tp.put(patch.getId(), props);
                                                }
                                            }
                                            // Cache this patch as under the VectorData d
                                            synchronized (stacked_patch_ids) {
                                                // sorted by stack index
                                                stacked_patch_ids.put(la.indexOf(patch), patch.getId());
                                            // Utils.log("Added patch for layer " + la + " with stack index " + la.indexOf(patch) + ", patch " + patch);
                                            }
                                            if (!layer_visited[0]) {
                                                // synch may fail to avoid adding it twice
                                                // but it's ok since it's a Set anyway
                                                layer_visited[0] = true;
                                                synchronized (src_layer_lids_used) {
                                                    src_layer_lids_used.add(la.getId());
                                                }
                                            }
                                        }
                                    }
                                }));
                            } catch (final Throwable t) {
                                IJError.print(t);
                                return;
                            }
                        }
                    }
                }
            }));
        }
        Utils.wait(dtasks);
        Utils.wait(ltasks);
    } catch (final Throwable t) {
        IJError.print(t);
    } finally {
        exec.shutdownNow();
    }
    return new ReferenceData(tp, underlying, src_layer_lids_used);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) VectorData(ini.trakem2.display.VectorData) HashSet(java.util.HashSet) Displayable(ini.trakem2.display.Displayable) TreeMap(java.util.TreeMap) Layer(ini.trakem2.display.Layer) Point(mpicbg.models.Point) Area(java.awt.geom.Area) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) Collection(java.util.Collection) Patch(ini.trakem2.display.Patch) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 9 with Displayable

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

the class AlignTask method alignSelection.

public static final void alignSelection(final Selection selection, final int m) throws Exception {
    final List<Patch> patches = new ArrayList<Patch>();
    for (final Displayable d : selection.getSelected()) if (d instanceof Patch)
        patches.add((Patch) d);
    final HashSet<Patch> fixedPatches = new HashSet<Patch>();
    // Add active Patch, if any, as the nail
    final Displayable active = selection.getActive();
    if (null != active && active instanceof Patch)
        fixedPatches.add((Patch) active);
    // Add all locked Patch instances to fixedPatches
    for (final Patch patch : patches) if (patch.isLocked())
        fixedPatches.add(patch);
    alignPatches(patches, fixedPatches, m);
}
Also used : Displayable(ini.trakem2.display.Displayable) ArrayList(java.util.ArrayList) Patch(ini.trakem2.display.Patch) HashSet(java.util.HashSet)

Example 10 with Displayable

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

the class AlignTask method transformPatchesAndVectorData.

/**
 * For registering within the same project instance.
 */
public static final void transformPatchesAndVectorData(final Collection<Patch> patches, final Runnable alignment) {
    if (patches.isEmpty()) {
        Utils.log("No patches to align!");
        return;
    }
    // 1 - Collect all VectorData to transform
    final ArrayList<Displayable> vdata = new ArrayList<Displayable>();
    final LayerSet ls = patches.iterator().next().getLayerSet();
    for (final Layer layer : ls.getLayers()) {
        vdata.addAll(layer.getDisplayables(VectorData.class, false, true));
    }
    vdata.addAll(ls.getZDisplayables(VectorData.class, true));
    // Perhaps none:
    if (vdata.isEmpty()) {
        alignment.run();
        return;
    }
    // 2 - Store current transformation of each Patch under any VectorData
    final HashSet<Long> lids = new HashSet<Long>();
    for (final Patch p : patches) lids.add(p.getLayer().getId());
    final ReferenceData rd = createTransformPropertiesTable(vdata, null, lids);
    // 3 - Align:
    alignment.run();
    // 4 - Transform VectorData instances to match the position of the Patch instances over which they were defined
    if (null != rd && !vdata.isEmpty())
        transformVectorData(rd, vdata, ls);
}
Also used : Displayable(ini.trakem2.display.Displayable) LayerSet(ini.trakem2.display.LayerSet) ArrayList(java.util.ArrayList) Layer(ini.trakem2.display.Layer) Patch(ini.trakem2.display.Patch) VectorData(ini.trakem2.display.VectorData) 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