Search in sources :

Example 16 with Bureaucrat

use of ini.trakem2.utils.Bureaucrat in project TrakEM2 by trakem2.

the class Loader method makeFlatImage.

/**
 * If the srcRect is null, makes a flat 8-bit or RGB image of the entire layer. Otherwise just of the srcRect. Checks first for enough memory and frees some if feasible.
 */
public Bureaucrat makeFlatImage(final Layer[] layer, final Rectangle srcRect, final double scale, final int c_alphas, final int type, final boolean force_to_file, final String format, final boolean quality, final Color background) {
    if (null == layer || 0 == layer.length) {
        Utils.log2("makeFlatImage: null or empty list of layers to process.");
        return null;
    }
    final Worker worker = new Worker("making flat images") {

        @Override
        public void run() {
            try {
                // 
                startedWorking();
                Rectangle srcRect_ = srcRect;
                if (null == srcRect_)
                    srcRect_ = layer[0].getParent().get2DBounds();
                ImagePlus imp = null;
                String target_dir = null;
                boolean choose_dir = force_to_file;
                // if not saving to a file:
                if (!force_to_file) {
                    final long size = (long) Math.ceil((srcRect_.width * scale) * (srcRect_.height * scale) * (ImagePlus.GRAY8 == type ? 1 : 4) * layer.length);
                    if (size > IJ.maxMemory() * 0.9) {
                        final YesNoCancelDialog yn = new YesNoCancelDialog(IJ.getInstance(), "WARNING", "The resulting stack of flat images is too large to fit in memory.\nChoose a directory to save the slices as an image sequence?");
                        if (yn.yesPressed()) {
                            choose_dir = true;
                        } else if (yn.cancelPressed()) {
                            finishedWorking();
                            return;
                        } else {
                            // your own risk
                            choose_dir = false;
                        }
                    }
                }
                if (choose_dir) {
                    final DirectoryChooser dc = new DirectoryChooser("Target directory");
                    target_dir = dc.getDirectory();
                    if (null == target_dir || target_dir.toLowerCase().startsWith("null")) {
                        finishedWorking();
                        return;
                    }
                    if (IJ.isWindows())
                        target_dir = target_dir.replace('\\', '/');
                    if (!target_dir.endsWith("/"))
                        target_dir += "/";
                }
                if (layer.length > 1) {
                    // Get all slices
                    ImageStack stack = null;
                    Utils.showProgress(0);
                    for (int i = 0; i < layer.length; i++) {
                        if (Thread.currentThread().isInterrupted())
                            return;
                        /* free memory */
                        releaseAll();
                        Utils.showProgress(i / (float) layer.length);
                        final ImagePlus slice = getFlatImage(layer[i], srcRect_, scale, c_alphas, type, Displayable.class, null, quality, background);
                        if (null == slice) {
                            Utils.log("Could not retrieve flat image for " + layer[i].toString());
                            continue;
                        }
                        if (null != target_dir) {
                            saveToPath(slice, target_dir, layer[i].getPrintableTitle(), ".tif");
                        } else {
                            if (null == stack)
                                stack = new ImageStack(slice.getWidth(), slice.getHeight());
                            stack.addSlice(layer[i].getProject().findLayerThing(layer[i]).toString(), slice.getProcessor());
                        }
                    }
                    Utils.showProgress(1);
                    if (null != stack) {
                        imp = new ImagePlus("z=" + layer[0].getZ() + " to z=" + layer[layer.length - 1].getZ(), stack);
                        final Calibration impCalibration = layer[0].getParent().getCalibrationCopy();
                        impCalibration.pixelWidth /= scale;
                        impCalibration.pixelHeight /= scale;
                        imp.setCalibration(impCalibration);
                    }
                } else {
                    imp = getFlatImage(layer[0], srcRect_, scale, c_alphas, type, Displayable.class, null, quality, background);
                    if (null != target_dir) {
                        saveToPath(imp, target_dir, layer[0].getPrintableTitle(), format);
                        // to prevent showing it
                        imp = null;
                    }
                }
                if (null != imp)
                    imp.show();
            } catch (final Throwable e) {
                IJError.print(e);
            }
            finishedWorking();
        }
    };
    // I miss my lisp macros, you have no idea
    return Bureaucrat.createAndStart(worker, layer[0].getProject());
}
Also used : ZDisplayable(ini.trakem2.display.ZDisplayable) Displayable(ini.trakem2.display.Displayable) ImageStack(ij.ImageStack) Rectangle(java.awt.Rectangle) Calibration(ij.measure.Calibration) ImagePlus(ij.ImagePlus) Worker(ini.trakem2.utils.Worker) YesNoCancelDialog(ij.gui.YesNoCancelDialog) DirectoryChooser(ij.io.DirectoryChooser)

Example 17 with Bureaucrat

use of ini.trakem2.utils.Bureaucrat in project TrakEM2 by trakem2.

the class Loader method importImage.

/**
 * Import an image into the given layer, in a separate task thread.
 */
public Bureaucrat importImage(final Layer layer, final double x, final double y, final String path, final boolean synch_mipmap_generation) {
    final Worker worker = new Worker("Importing image") {

        @Override
        public void run() {
            startedWorking();
            try {
                // //
                if (null == layer) {
                    Utils.log("Can't import. No layer found.");
                    finishedWorking();
                    return;
                }
                final Patch p = importImage(layer.getProject(), x, y, path, synch_mipmap_generation);
                if (null != p) {
                    synchronized (layer) {
                        layer.add(p);
                    }
                    layer.getParent().enlargeToFit(p, LayerSet.NORTHWEST);
                }
            // //
            } catch (final Exception e) {
                IJError.print(e);
            }
            finishedWorking();
        }
    };
    return Bureaucrat.createAndStart(worker, layer.getProject());
}
Also used : Worker(ini.trakem2.utils.Worker) Patch(ini.trakem2.display.Patch) IOException(java.io.IOException) FormatException(loci.formats.FormatException)

Example 18 with Bureaucrat

use of ini.trakem2.utils.Bureaucrat in project TrakEM2 by trakem2.

the class Loader method importSequenceAsGrid.

/**
 * Open one of the images to find out the dimensions, and get a good guess at what is the desirable scale for doing phase- and cross-correlations with about 512x512 images.
 */
/*
	private int getCCScaleGuess(final File images_dir, final String[] all_images) {
		try {
			if (null != all_images && all_images.length > 0) {
				Utils.showStatus("Opening one image ... ", false);
				String sdir = images_dir.getAbsolutePath().replace('\\', '/');
				if (!sdir.endsWith("/")) sdir += "/";
				IJ.redirectErrorMessages();
				ImagePlus imp = openImagePlus(sdir + all_images[0]);
				if (null != imp) {
					int w = imp.getWidth();
					int h = imp.getHeight();
					flush(imp);
					imp = null;
					int cc_scale = (int)((512.0 / (w > h ? w : h)) * 100);
					if (cc_scale > 100) return 100;
					return cc_scale;
				}
			}
		} catch (Exception e) {
			Utils.log2("Could not get an estimate for the optimal scale.");
		}
		return 25;
	}
	*/
/**
 * Import a sequence of images as a grid, and put them in the layer. If the directory (@param dir) is null, it'll be asked for. The image_file_names can be null, and in any case it's only the names, not the paths.
 */
public Bureaucrat importSequenceAsGrid(final Layer first_layer, String dir, final String[] image_file_names) {
    String[] all_images = null;
    // first file
    String file = null;
    File images_dir = null;
    if (null != dir && null != image_file_names) {
        all_images = image_file_names;
        images_dir = new File(dir);
    } else if (null == dir) {
        final String[] dn = Utils.selectFile("Select first image");
        if (null == dn)
            return null;
        dir = dn[0];
        file = dn[1];
        images_dir = new File(dir);
    } else {
        images_dir = new File(dir);
        if (!(images_dir.exists() && images_dir.isDirectory())) {
            Utils.showMessage("Something went wrong:\n\tCan't find directory " + dir);
            return null;
        }
    }
    if (null == image_file_names)
        all_images = images_dir.list(new ini.trakem2.io.ImageFileFilter("", null));
    if (null == file && all_images.length > 0) {
        file = all_images[0];
    }
    final int n_max = all_images.length;
    // reasonable estimate
    final int side = (int) Math.floor(Math.sqrt(n_max));
    final GenericDialog gd = new GenericDialog("Conventions");
    gd.addStringField("file_name_matches: ", "");
    gd.addNumericField("first_image: ", 1, 0);
    gd.addNumericField("last_image: ", n_max, 0);
    gd.addCheckbox("Reverse list order", false);
    gd.addNumericField("number_of_rows: ", side, 0);
    gd.addNumericField("number_of_columns: ", side, 0);
    gd.addNumericField("number_of_slices: ", 1, 0);
    gd.addMessage("The top left coordinate for the imported grid:");
    gd.addNumericField("base_x: ", 0, 3);
    gd.addNumericField("base_y: ", 0, 3);
    gd.addMessage("Amount of image overlap, in pixels");
    // as asked by Joachim Walter
    gd.addNumericField("bottom-top overlap: ", 0, 2);
    gd.addNumericField("left-right overlap: ", 0, 2);
    gd.addCheckbox("link images", false);
    gd.addCheckbox("montage with phase correlation", true);
    gd.addCheckbox("homogenize_contrast", false);
    gd.showDialog();
    if (gd.wasCanceled())
        return null;
    final String regex = gd.getNextString();
    // avoid destroying backslashes
    Utils.log2(new StringBuilder("using regex: ").append(regex).toString());
    int first = (int) gd.getNextNumber();
    if (first < 1)
        first = 1;
    int last = (int) gd.getNextNumber();
    if (last < 1)
        last = 1;
    if (last < first) {
        Utils.showMessage("Last is smaller that first!");
        return null;
    }
    final boolean reverse_order = gd.getNextBoolean();
    final int n_rows = (int) gd.getNextNumber();
    final int n_cols = (int) gd.getNextNumber();
    final int n_slices = (int) gd.getNextNumber();
    final double bx = gd.getNextNumber();
    final double by = gd.getNextNumber();
    final double bt_overlap = gd.getNextNumber();
    final double lr_overlap = gd.getNextNumber();
    final boolean link_images = gd.getNextBoolean();
    final boolean stitch_tiles = gd.getNextBoolean();
    final boolean homogenize_contrast = gd.getNextBoolean();
    String[] file_names = null;
    if (null == image_file_names) {
        file_names = images_dir.list(new ini.trakem2.io.ImageFileFilter(regex, null));
        // assumes 001, 002, 003 ... that style, since it does binary sorting of strings
        Arrays.sort(file_names);
        if (reverse_order) {
            // flip in place
            for (int i = file_names.length / 2; i > -1; i--) {
                final String tmp = file_names[i];
                final int j = file_names.length - 1 - i;
                file_names[i] = file_names[j];
                file_names[j] = tmp;
            }
        }
    } else {
        file_names = all_images;
    }
    if (0 == file_names.length) {
        Utils.showMessage("No images found.");
        return null;
    }
    // check if the selected image is in the list. Otherwise, shift selected image to the first of the included ones.
    boolean found_first = false;
    for (int i = 0; i < file_names.length; i++) {
        if (file.equals(file_names[i])) {
            found_first = true;
            break;
        }
    }
    if (!found_first) {
        file = file_names[0];
        Utils.log("Using " + file + " as the reference image for size.");
    }
    // crop list
    if (last > file_names.length)
        last = file_names.length - 1;
    if (first < 1)
        first = 1;
    if (1 != first || last != file_names.length) {
        Utils.log("Cropping list.");
        final String[] file_names2 = new String[last - first + 1];
        System.arraycopy(file_names, first - 1, file_names2, 0, file_names2.length);
        file_names = file_names2;
    }
    // should be multiple of rows and cols and slices
    if (file_names.length != n_rows * n_cols * n_slices) {
        Utils.log("ERROR: rows * cols * slices does not match with the number of selected images.");
        Utils.log("n_images:" + file_names.length + "  rows,cols,slices : " + n_rows + "," + n_cols + "," + n_slices + "  total=" + n_rows * n_cols * n_slices);
        return null;
    }
    // I luv java
    final String[] file_names_ = file_names;
    final String dir_ = dir;
    // the first file
    final String file_ = file;
    final double bt_overlap_ = bt_overlap;
    final double lr_overlap_ = lr_overlap;
    return Bureaucrat.createAndStart(new Worker.Task("Importing", true) {

        @Override
        public void exec() {
            StitchingTEM.PhaseCorrelationParam pc_param = null;
            // Slice up list:
            for (int sl = 0; sl < n_slices; sl++) {
                if (Thread.currentThread().isInterrupted() || hasQuitted())
                    return;
                Utils.log("Importing " + (sl + 1) + "/" + n_slices);
                final int start = sl * n_rows * n_cols;
                final ArrayList<String[]> cols = new ArrayList<String[]>();
                for (int i = 0; i < n_cols; i++) {
                    final String[] col = new String[n_rows];
                    for (int j = 0; j < n_rows; j++) {
                        col[j] = file_names_[start + j * n_cols + i];
                    }
                    cols.add(col);
                }
                final Layer layer = 0 == sl ? first_layer : first_layer.getParent().getLayer(first_layer.getZ() + first_layer.getThickness() * sl, first_layer.getThickness(), true);
                if (stitch_tiles && null == pc_param) {
                    pc_param = new StitchingTEM.PhaseCorrelationParam();
                    pc_param.setup(layer);
                }
                insertGrid(layer, dir_, file_, n_rows * n_cols, cols, bx, by, bt_overlap_, lr_overlap_, link_images, stitch_tiles, homogenize_contrast, pc_param, this);
            }
        }
    }, first_layer.getProject());
}
Also used : ArrayList(java.util.ArrayList) ImageFileFilter(ini.trakem2.io.ImageFileFilter) Layer(ini.trakem2.display.Layer) ImageFileFilter(ini.trakem2.io.ImageFileFilter) GenericDialog(ij.gui.GenericDialog) Worker(ini.trakem2.utils.Worker) File(java.io.File)

Example 19 with Bureaucrat

use of ini.trakem2.utils.Bureaucrat in project TrakEM2 by trakem2.

the class Loader method importImages.

/**
 * <p>Import images from the given text file, which is expected to contain 4 columns or optionally 9 columns:</p>
 * <ul>
 * <li>column 1: image file path (if base_dir is not null, it will be prepended)</li>
 * <li>column 2: x coord [px]</li>
 * <li>column 3: y coord [px]</li>
 * <li>column 4: z coord [px] (layer_thickness will be multiplied to it if not zero)</li>
 * </ul>
 * <p>optional columns, if a property is not known, it can be set to "-" which makes TrakEM2 open the file and find out by itself</p>
 * <ul>
 * <li>column 5: width [px]</li>
 * <li>column 6: height [px]</li>
 * <li>column 7: min intensity [double] (for screen display)</li>
 * <li>column 8: max intensity [double] (for screen display)</li>
 * <li>column 9: type [integer] (pixel types according to ImagepPlus types: 0=8bit int gray, 1=16bit int gray, 2=32bit float gray, 3=8bit indexed color, 4=32-bit RGB color</li>
 * </ul>
 *
 * <p>This function implements the "Import from text file" command.</p>
 *
 * <p>Layers will be automatically created as needed inside the LayerSet to which the given ref_layer belongs.</p>
 * <p>
 * The text file can contain comments that start with the # sign.
 * </p>
 * <p>
 * Images will be imported in parallel, using as many cores as your machine has.
 * </p>
 * @param calibration_ transforms the read coordinates into pixel coordinates, including x,y,z, and layer thickness.
 * @param scale_ Between 0 and 1. When lower than 1, a preprocessor script is created for the imported images, to scale them down.
 */
public Bureaucrat importImages(Layer ref_layer, String abs_text_file_path_, String column_separator_, double layer_thickness_, double calibration_, boolean homogenize_contrast_, float scale_, int border_width_) {
    // check parameters: ask for good ones if necessary
    if (null == abs_text_file_path_) {
        final String[] file = Utils.selectFile("Select text file");
        // user canceled dialog
        if (null == file)
            return null;
        abs_text_file_path_ = file[0] + file[1];
    }
    if (null == column_separator_ || 0 == column_separator_.length() || Double.isNaN(layer_thickness_) || layer_thickness_ <= 0 || Double.isNaN(calibration_) || calibration_ <= 0) {
        final Calibration cal = ref_layer.getParent().getCalibrationCopy();
        final GenericDialog gdd = new GenericDialog("Options");
        final String[] separators = new String[] { "tab", "space", "comma (,)" };
        gdd.addMessage("Choose a layer to act as the zero for the Z coordinates:");
        Utils.addLayerChoice("Base layer", ref_layer, gdd);
        gdd.addChoice("Column separator: ", separators, separators[0]);
        // default: 60 nm
        gdd.addNumericField("Layer thickness: ", cal.pixelDepth, 2);
        gdd.addNumericField("Calibration (data to pixels): ", 1, 2);
        gdd.addCheckbox("Homogenize contrast layer-wise", homogenize_contrast_);
        gdd.addSlider("Scale:", 0, 100, 100);
        gdd.addNumericField("Hide border with alpha mask", 0, 0, 6, "pixels");
        gdd.showDialog();
        if (gdd.wasCanceled())
            return null;
        layer_thickness_ = gdd.getNextNumber();
        if (layer_thickness_ < 0 || Double.isNaN(layer_thickness_)) {
            Utils.log("Improper layer thickness value.");
            return null;
        }
        calibration_ = gdd.getNextNumber();
        if (0 == calibration_ || Double.isNaN(calibration_)) {
            Utils.log("Improper calibration value.");
            return null;
        }
        // not pixelDepth!
        layer_thickness_ /= cal.pixelWidth;
        ref_layer = ref_layer.getParent().getLayer(gdd.getNextChoiceIndex());
        column_separator_ = "\t";
        switch(gdd.getNextChoiceIndex()) {
            case 1:
                column_separator_ = " ";
                break;
            case 2:
                column_separator_ = ",";
                break;
            default:
                break;
        }
        homogenize_contrast_ = gdd.getNextBoolean();
        final double sc = gdd.getNextNumber();
        if (Double.isNaN(sc))
            scale_ = 1.0f;
        else
            scale_ = ((float) sc) / 100.0f;
        final int border = (int) gdd.getNextNumber();
        if (border < 0) {
            Utils.log("Nonsensical border value: " + border);
            return null;
        }
        border_width_ = border;
    }
    if (Float.isNaN(scale_) || scale_ < 0 || scale_ > 1) {
        Utils.log("Non-sensical scale: " + scale_ + "\nUsing scale of 1 instead.");
        scale_ = 1;
    }
    // make vars accessible from inner threads:
    final Layer base_layer = ref_layer;
    final String abs_text_file_path = abs_text_file_path_;
    final String column_separator = column_separator_;
    final double layer_thickness = layer_thickness_;
    final double calibration = calibration_;
    final boolean homogenize_contrast = homogenize_contrast_;
    final float scale = (float) scale_;
    final int border_width = border_width_;
    return Bureaucrat.createAndStart(new Worker.Task("Importing images", true) {

        @Override
        public void exec() {
            try {
                // 1 - read text file
                final String[] lines = Utils.openTextFileLines(abs_text_file_path);
                if (null == lines || 0 == lines.length) {
                    Utils.log2("No images to import from " + abs_text_file_path);
                    return;
                }
                ContrastEnhancerWrapper cew = null;
                if (homogenize_contrast) {
                    cew = new ContrastEnhancerWrapper();
                    cew.showDialog();
                }
                final String sep2 = column_separator + column_separator;
                // 2 - set a base dir path if necessary
                String base_dir = null;
                // to wait on mipmap regeneration
                final Vector<Future<?>> fus = new Vector<Future<?>>();
                final LayerSet layer_set = base_layer.getParent();
                final double z_zero = base_layer.getZ();
                final AtomicInteger n_imported = new AtomicInteger(0);
                final Set<Layer> touched_layers = new HashSet<Layer>();
                final int NP = Runtime.getRuntime().availableProcessors();
                int np = NP;
                switch(np) {
                    case 1:
                    case 2:
                        break;
                    default:
                        np = np / 2;
                        break;
                }
                final ExecutorService ex = Utils.newFixedThreadPool(np, "import-images");
                final List<Future<?>> imported = new ArrayList<Future<?>>();
                final Worker wo = this;
                final String script_path;
                // If scale is at least 1/100 lower than 1, then:
                if (Math.abs(scale - (int) scale) > 0.01) {
                    // Assume source and target sigma of 0.5
                    final double sigma = Math.sqrt(Math.pow(1 / scale, 2) - 0.25);
                    final String script = new StringBuilder().append("import ij.ImagePlus;\n").append("import ij.process.ImageProcessor;\n").append("import ij.plugin.filter.GaussianBlur;\n").append("GaussianBlur blur = new GaussianBlur();\n").append(// as in ij.plugin.filter.GaussianBlur
                    "double accuracy = (imp.getType() == ImagePlus.GRAY8 || imp.getType() == ImagePlus.COLOR_RGB) ? 0.002 : 0.0002;\n").append("imp.getProcessor().setInterpolationMethod(ImageProcessor.NONE);\n").append("blur.blurGaussian(imp.getProcessor(),").append(sigma).append(',').append(sigma).append(",accuracy);\n").append("imp.setProcessor(imp.getTitle(), imp.getProcessor().resize((int)(imp.getWidth() * ").append(scale).append("), (int)(imp.getHeight() * ").append(scale).append(")));").toString();
                    File f = new File(getStorageFolder() + "resize-" + scale + ".bsh");
                    int v = 1;
                    while (f.exists()) {
                        f = new File(getStorageFolder() + "resize-" + scale + "." + v + ".bsh");
                        v++;
                    }
                    script_path = Utils.saveToFile(f, script) ? f.getAbsolutePath() : null;
                    if (null == script_path) {
                        Utils.log("Could NOT save a preprocessor script for image scaling\nat path " + f.getAbsolutePath());
                    }
                } else {
                    script_path = null;
                }
                Utils.log("Scaling script path is " + script_path);
                final AtomicReference<Triple<Integer, Integer, ByteProcessor>> last_mask = new AtomicReference<Triple<Integer, Integer, ByteProcessor>>();
                // 3 - parse each line
                for (int i = 0; i < lines.length; i++) {
                    if (Thread.currentThread().isInterrupted() || hasQuitted()) {
                        this.quit();
                        return;
                    }
                    // process line
                    // first thing is the backslash removal, before they get processed at all
                    String line = lines[i].replace('\\', '/').trim();
                    final int ic = line.indexOf('#');
                    // remove comment at end of line if any
                    if (-1 != ic)
                        line = line.substring(0, ic);
                    if (0 == line.length() || '#' == line.charAt(0))
                        continue;
                    // reduce line, so that separators are really unique
                    while (-1 != line.indexOf(sep2)) {
                        line = line.replaceAll(sep2, column_separator);
                    }
                    final String[] column = line.split(column_separator);
                    if (column.length < 4) {
                        Utils.log("Less than 4 columns: can't import from line " + i + " : " + line);
                        continue;
                    }
                    // obtain coordinates
                    double x = 0, y = 0, z = 0;
                    try {
                        x = Double.parseDouble(column[1].trim());
                        y = Double.parseDouble(column[2].trim());
                        z = Double.parseDouble(column[3].trim());
                    } catch (final NumberFormatException nfe) {
                        Utils.log("Non-numeric value in a numeric column at line " + i + " : " + line);
                        continue;
                    }
                    x *= calibration;
                    y *= calibration;
                    z = z * calibration + z_zero;
                    // obtain path
                    String path = column[0].trim();
                    if (0 == path.length())
                        continue;
                    // check if path is relative
                    if ((!IJ.isWindows() && '/' != path.charAt(0)) || (IJ.isWindows() && 1 != path.indexOf(":/"))) {
                        // path is relative.
                        if (null == base_dir) {
                            // may not be null if another thread that got the lock first set it to non-null
                            // Ask for source directory
                            final DirectoryChooser dc = new DirectoryChooser("Choose source directory");
                            final String dir = dc.getDirectory();
                            if (null == dir) {
                                // quit all threads
                                return;
                            }
                            base_dir = Utils.fixDir(dir);
                        }
                    }
                    if (null != base_dir)
                        path = base_dir + path;
                    final File f = new File(path);
                    if (!f.exists()) {
                        Utils.log("No file found for path " + path);
                        continue;
                    }
                    // will create a new Layer if necessary
                    final Layer layer = layer_set.getLayer(z, layer_thickness, true);
                    touched_layers.add(layer);
                    final String imagefilepath = path;
                    final double xx = x * scale;
                    final double yy = y * scale;
                    final Callable<Patch> creator;
                    if (column.length >= 9) {
                        creator = new Callable<Patch>() {

                            private final int parseInt(final String t) {
                                if (t.equals("-"))
                                    return -1;
                                return Integer.parseInt(t);
                            }

                            private final double parseDouble(final String t) {
                                if (t.equals("-"))
                                    return Double.NaN;
                                return Double.parseDouble(t);
                            }

                            @Override
                            public Patch call() throws Exception {
                                int o_width = parseInt(column[4].trim());
                                int o_height = parseInt(column[5].trim());
                                double min = parseDouble(column[6].trim());
                                double max = parseDouble(column[7].trim());
                                int type = parseInt(column[8].trim());
                                if (-1 == type || -1 == o_width || -1 == o_height) {
                                    // Read them from the file header
                                    final ImageFileHeader ifh = new ImageFileHeader(imagefilepath);
                                    o_width = ifh.width;
                                    o_height = ifh.height;
                                    type = ifh.type;
                                    if (!ifh.isSupportedType()) {
                                        Utils.log("Incompatible image type: " + imagefilepath);
                                        return null;
                                    }
                                }
                                ImagePlus imp = null;
                                if (Double.isNaN(min) || Double.isNaN(max)) {
                                    imp = openImagePlus(imagefilepath);
                                    min = imp.getProcessor().getMin();
                                    max = imp.getProcessor().getMax();
                                }
                                final Patch patch = new Patch(layer.getProject(), new File(imagefilepath).getName(), o_width, o_height, o_width, o_height, type, 1.0f, Color.yellow, false, min, max, new AffineTransform(1, 0, 0, 1, xx, yy), imagefilepath);
                                if (null != script_path && null != imp) {
                                    // For use in setting the preprocessor script
                                    cacheImagePlus(patch.getId(), imp);
                                }
                                return patch;
                            }
                        };
                    } else {
                        creator = new Callable<Patch>() {

                            @Override
                            public Patch call() throws Exception {
                                IJ.redirectErrorMessages();
                                final ImageFileHeader ifh = new ImageFileHeader(imagefilepath);
                                final int o_width = ifh.width;
                                final int o_height = ifh.height;
                                final int type = ifh.type;
                                if (!ifh.isSupportedType()) {
                                    Utils.log("Incompatible image type: " + imagefilepath);
                                    return null;
                                }
                                double min = 0;
                                double max = 255;
                                switch(type) {
                                    case ImagePlus.GRAY16:
                                    case ImagePlus.GRAY32:
                                        // Determine suitable min and max
                                        // TODO Stream through the image, do not load it!
                                        final ImagePlus imp = openImagePlus(imagefilepath);
                                        if (null == imp) {
                                            Utils.log("Ignoring unopenable image from " + imagefilepath);
                                            return null;
                                        }
                                        min = imp.getProcessor().getMin();
                                        max = imp.getProcessor().getMax();
                                        break;
                                }
                                // add Patch
                                final Patch patch = new Patch(layer.getProject(), new File(imagefilepath).getName(), o_width, o_height, o_width, o_height, type, 1.0f, Color.yellow, false, min, max, new AffineTransform(1, 0, 0, 1, xx, yy), imagefilepath);
                                return patch;
                            }
                        };
                    }
                    // Otherwise, images would end up loaded twice for no reason
                    if (0 == (i % (NP + NP))) {
                        final ArrayList<Future<?>> a = new ArrayList<Future<?>>(NP + NP);
                        synchronized (fus) {
                            // .add is also synchronized, fus is a Vector
                            int k = 0;
                            while (!fus.isEmpty() && k < NP) {
                                a.add(fus.remove(0));
                                k++;
                            }
                        }
                        for (final Future<?> fu : a) {
                            try {
                                if (wo.hasQuitted())
                                    return;
                                fu.get();
                            } catch (final Throwable t) {
                                t.printStackTrace();
                            }
                        }
                    }
                    imported.add(ex.submit(new Runnable() {

                        @Override
                        public void run() {
                            if (wo.hasQuitted())
                                return;
                            /* */
                            IJ.redirectErrorMessages();
                            Patch patch;
                            try {
                                patch = creator.call();
                            } catch (final Exception e) {
                                e.printStackTrace();
                                Utils.log("Could not load patch from " + imagefilepath);
                                return;
                            }
                            // Set the script if any
                            if (null != script_path) {
                                try {
                                    patch.setPreprocessorScriptPath(script_path);
                                } catch (final Throwable t) {
                                    Utils.log("FAILED to set a scaling preprocessor script to patch " + patch);
                                    IJError.print(t);
                                }
                            }
                            // Set an alpha mask to crop away the borders
                            if (border_width > 0) {
                                final Triple<Integer, Integer, ByteProcessor> m = last_mask.get();
                                if (null != m && m.a == patch.getOWidth() && m.b == patch.getOHeight()) {
                                    // Reuse
                                    patch.setAlphaMask(m.c);
                                } else {
                                    // Create new mask
                                    final ByteProcessor mask = new ByteProcessor(patch.getOWidth(), patch.getOHeight());
                                    mask.setValue(255);
                                    mask.setRoi(new Roi(border_width, border_width, mask.getWidth() - 2 * border_width, mask.getHeight() - 2 * border_width));
                                    mask.fill();
                                    patch.setAlphaMask(mask);
                                    // Store as last
                                    last_mask.set(new Triple<Integer, Integer, ByteProcessor>(mask.getWidth(), mask.getHeight(), mask));
                                }
                            }
                            if (!homogenize_contrast) {
                                fus.add(regenerateMipMaps(patch));
                            }
                            synchronized (layer) {
                                layer.add(patch, true);
                            }
                            wo.setTaskName("Imported " + (n_imported.incrementAndGet() + 1) + "/" + lines.length);
                        }
                    }));
                }
                Utils.wait(imported);
                ex.shutdown();
                if (0 == n_imported.get()) {
                    Utils.log("No images imported.");
                    return;
                }
                base_layer.getParent().setMinimumDimensions();
                Display.repaint(base_layer.getParent());
                recreateBuckets(touched_layers);
                if (homogenize_contrast) {
                    setTaskName("Enhance contrast");
                    // layer-wise (layer order is irrelevant):
                    cew.applyLayerWise(touched_layers);
                    cew.shutdown();
                }
                Utils.wait(fus);
            } catch (final Exception e) {
                IJError.print(e);
            }
        }
    }, base_layer.getProject());
}
Also used : ByteProcessor(ij.process.ByteProcessor) Set(java.util.Set) HashSet(java.util.HashSet) LayerSet(ini.trakem2.display.LayerSet) ArrayList(java.util.ArrayList) Callable(java.util.concurrent.Callable) GenericDialog(ij.gui.GenericDialog) Worker(ini.trakem2.utils.Worker) AreaList(ini.trakem2.display.AreaList) ArrayList(java.util.ArrayList) List(java.util.List) Vector(java.util.Vector) LayerSet(ini.trakem2.display.LayerSet) AtomicReference(java.util.concurrent.atomic.AtomicReference) ImageFileHeader(ini.trakem2.io.ImageFileHeader) Calibration(ij.measure.Calibration) Layer(ini.trakem2.display.Layer) ImagePlus(ij.ImagePlus) Roi(ij.gui.Roi) IOException(java.io.IOException) FormatException(loci.formats.FormatException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Triple(mpicbg.trakem2.util.Triple) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) AffineTransform(java.awt.geom.AffineTransform) ContrastEnhancerWrapper(ini.trakem2.imaging.ContrastEnhancerWrapper) File(java.io.File) Patch(ini.trakem2.display.Patch) DirectoryChooser(ij.io.DirectoryChooser)

Example 20 with Bureaucrat

use of ini.trakem2.utils.Bureaucrat in project TrakEM2 by trakem2.

the class DNDInsertImage method importImageFile.

private boolean importImageFile(File f, String path, Point point) throws Exception {
    if (f.exists()) {
        final Layer layer = display.getLayer();
        Bureaucrat burro = null;
        if (f.isDirectory()) {
            // ask:
            GenericDialog gd = new GenericDialog("Import directory");
            String[] choice = new String[] { "Stack", "Grid", "Sequence as grid" };
            gd.addChoice("Directory as: ", choice, choice[0]);
            gd.showDialog();
            if (gd.wasCanceled()) {
                // the user cancel it, so all is ok.
                return true;
            }
            display.getLayerSet().addLayerContentStep(layer);
            switch(gd.getNextChoiceIndex()) {
                case // as stack
                0:
                    // if importing image sequence as a stack:
                    // don't filter by name  "^[^\\.].*[\\.][a-zA-Z1-9_]{3,4}$"
                    String[] names = f.list(new ImageFileFilter());
                    Utils.log2("stack size: " + names.length);
                    for (int i = 0; i < names.length; i++) {
                        Utils.log2(names[i]);
                    }
                    Arrays.sort(names);
                    // I don't care about the dimensions
                    VirtualStack stack = new VirtualStack(10, 10, null, f.getAbsolutePath().replace('\\', '/'));
                    for (int k = 0; k < names.length; k++) {
                        IJ.redirectErrorMessages();
                        // ignore trakem2 files
                        if (names[k].toLowerCase().endsWith(".xml"))
                            continue;
                        stack.addSlice(names[k]);
                    }
                    if (stack.getSize() > 0) {
                        burro = display.getProject().getLoader().importStack(layer, point.x, point.y, new ImagePlus("stack", stack), true, path, false);
                    }
                    break;
                case // as grid
                1:
                    burro = display.getProject().getLoader().importGrid(layer, path);
                    break;
                case // sequence as grid
                2:
                    burro = display.getProject().getLoader().importSequenceAsGrid(layer, path);
                    break;
            }
        } else {
            layer.getParent().addLayerContentStep(layer);
            // single image file (single image or a stack)
            burro = display.getProject().getLoader().importImage(layer, point.x, point.y, path, false);
        }
        if (null != burro) {
            burro.addPostTask(new Runnable() {

                public void run() {
                    // The current state
                    layer.getParent().addLayerContentStep(layer);
                }
            });
        }
        return true;
    } else {
        Utils.log("File not found: " + path);
        return false;
    }
}
Also used : GenericDialog(ij.gui.GenericDialog) VirtualStack(ij.VirtualStack) Layer(ini.trakem2.display.Layer) ImageFileFilter(ini.trakem2.io.ImageFileFilter) ImagePlus(ij.ImagePlus) Point(java.awt.Point)

Aggregations

Worker (ini.trakem2.utils.Worker)26 ArrayList (java.util.ArrayList)12 GenericDialog (ij.gui.GenericDialog)11 File (java.io.File)11 ImagePlus (ij.ImagePlus)10 Bureaucrat (ini.trakem2.utils.Bureaucrat)8 Rectangle (java.awt.Rectangle)8 Patch (ini.trakem2.display.Patch)7 NoninvertibleTransformException (java.awt.geom.NoninvertibleTransformException)7 IOException (java.io.IOException)7 HashSet (java.util.HashSet)7 Project (ini.trakem2.Project)6 FormatException (loci.formats.FormatException)6 DirectoryChooser (ij.io.DirectoryChooser)5 Layer (ini.trakem2.display.Layer)5 Point (java.awt.Point)5 TreeMap (java.util.TreeMap)5 Future (java.util.concurrent.Future)5 Displayable (ini.trakem2.display.Displayable)4 DBObject (ini.trakem2.persistence.DBObject)4