Search in sources :

Example 16 with ShortProcessor

use of ij.process.ShortProcessor in project GDSC-SMLM by aherbert.

the class PcPalmMolecules method drawImage.

/**
 * Draw an image of the molecules.
 *
 * @param molecules the molecules
 * @param minx the minx
 * @param miny the miny
 * @param maxx the maxx
 * @param maxy the maxy
 * @param nmPerPixel the nm per pixel
 * @param checkBounds Set to true to check the molecules is within the bounds
 * @param binary the binary
 * @return the image
 */
static ImageProcessor drawImage(List<Molecule> molecules, double minx, double miny, double maxx, double maxy, double nmPerPixel, boolean checkBounds, boolean binary) {
    final double scalex = maxx - minx;
    final double scaley = maxy - miny;
    final int width = (int) Math.round(scalex / nmPerPixel) + 1;
    final int height = (int) Math.round(scaley / nmPerPixel) + 1;
    // ***
    if (binary) {
        final byte[] data = new byte[width * height];
        for (final Molecule m : molecules) {
            if (checkBounds) {
                if (m.x < minx || m.x >= maxx || m.y < miny || m.y >= maxy) {
                    continue;
                }
            }
            // Shift to the origin. This makes the image more memory efficient.
            final int x = (int) Math.round((m.x - minx) / nmPerPixel);
            final int y = (int) Math.round((m.y - miny) / nmPerPixel);
            final int index = y * width + x;
            // Construct a binary image
            data[index] = (byte) 1;
        }
        final ByteProcessor ip = new ByteProcessor(width, height, data, null);
        ip.setMinAndMax(0, 1);
        return ip;
    }
    final short[] data = new short[width * height];
    for (final Molecule m : molecules) {
        if (checkBounds && (m.x < minx || m.x >= maxx || m.y < miny || m.y >= maxy)) {
            continue;
        }
        // Shift to the origin. This makes the image more memory efficient.
        final int x = (int) Math.round((m.x - minx) / nmPerPixel);
        final int y = (int) Math.round((m.y - miny) / nmPerPixel);
        final int index = y * width + x;
        // Construct a count image
        data[index]++;
    }
    final ShortProcessor ip = new ShortProcessor(width, height, data, null);
    ip.setMinAndMax(0, MathUtils.max(data));
    return ip;
}
Also used : ByteProcessor(ij.process.ByteProcessor) WeightedObservedPoint(org.apache.commons.math3.fitting.WeightedObservedPoint) ClusterPoint(uk.ac.sussex.gdsc.core.clustering.ClusterPoint) ShortProcessor(ij.process.ShortProcessor)

Example 17 with ShortProcessor

use of ij.process.ShortProcessor in project GDSC-SMLM by aherbert.

the class GaussianFit method runFinal.

/**
 * Perform fitting using the chosen maxima. Update the overlay if successful.
 *
 * @param ip The input image
 */
private void runFinal(ImageProcessor ip) {
    ip.reset();
    final Rectangle bounds = ip.getRoi();
    // Crop to the ROI
    final float[] data = ImageJImageConverter.getData(ip);
    final int width = bounds.width;
    final int height = bounds.height;
    // Sort the maxima
    float[] smoothData = data;
    if (getSmooth() > 0) {
        // Smoothing destructively modifies the data so create a copy
        smoothData = Arrays.copyOf(data, width * height);
        final BlockMeanFilter filter = new BlockMeanFilter();
        if (settings.smooth <= settings.border) {
            filter.stripedBlockFilterInternal(smoothData, width, height, (float) settings.smooth);
        } else {
            filter.stripedBlockFilter(smoothData, width, height, (float) settings.smooth);
        }
    }
    SortUtils.sortIndices(maxIndices, smoothData, true);
    // Show the candidate peaks
    if (maxIndices.length > 0) {
        final String message = String.format("Identified %d peaks", maxIndices.length);
        if (isLogProgress()) {
            IJ.log(message);
            for (final int index : maxIndices) {
                IJ.log(String.format("  %.2f @ [%d,%d]", data[index], bounds.x + index % width, bounds.y + index / width));
            }
        }
        // Check whether to run if the number of peaks is large
        if (maxIndices.length > 10) {
            final GenericDialog gd = new GenericDialog("Warning");
            gd.addMessage(message + "\nDo you want to fit?");
            gd.showDialog();
            if (gd.wasCanceled()) {
                return;
            }
        }
    } else {
        IJ.log("No maxima identified");
        return;
    }
    results = new ImageJTablePeakResults(settings.showDeviations, imp.getTitle() + " [" + imp.getCurrentSlice() + "]");
    final CalibrationWriter cw = new CalibrationWriter();
    cw.setIntensityUnit(IntensityUnit.COUNT);
    cw.setDistanceUnit(DistanceUnit.PIXEL);
    cw.setAngleUnit(AngleUnit.RADIAN);
    results.setCalibration(cw.getCalibration());
    results.setPsf(PsfProtosHelper.getDefaultPsf(getPsfType()));
    results.setShowFittingData(true);
    results.setAngleUnit(AngleUnit.DEGREE);
    results.begin();
    // Perform the Gaussian fit
    long ellapsed = 0;
    final FloatProcessor renderedImage = settings.showFit ? new FloatProcessor(ip.getWidth(), ip.getHeight()) : null;
    if (!settings.singleFit) {
        if (isLogProgress()) {
            IJ.log("Combined fit");
        }
        // Estimate height from smoothed data
        final double[] estimatedHeights = new double[maxIndices.length];
        for (int i = 0; i < estimatedHeights.length; i++) {
            estimatedHeights[i] = smoothData[maxIndices[i]];
        }
        final FitConfiguration config = new FitConfiguration();
        setupPeakFiltering(config);
        final long time = System.nanoTime();
        final double[] params = fitMultiple(data, width, height, maxIndices, estimatedHeights);
        ellapsed = System.nanoTime() - time;
        if (params != null) {
            // Copy all the valid parameters into a new array
            final double[] validParams = new double[params.length];
            int count = 0;
            int validPeaks = 0;
            validParams[count++] = params[0];
            final double[] initialParams = convertParameters(fitResult.getInitialParameters());
            final double[] paramsDev = convertParameters(fitResult.getParameterDeviations());
            final Rectangle regionBounds = new Rectangle();
            final float[] xpoints = new float[maxIndices.length];
            final float[] ypoints = new float[maxIndices.length];
            int npoints = 0;
            for (int i = 1, n = 0; i < params.length; i += Gaussian2DFunction.PARAMETERS_PER_PEAK, n++) {
                final int y = maxIndices[n] / width;
                final int x = maxIndices[n] % width;
                // Check the peak is a good fit
                if (settings.filterResults && config.validatePeak(n, initialParams, params, paramsDev) != FitStatus.OK) {
                    continue;
                }
                if (settings.showFit) {
                    // Copy the valid parameters before there are adjusted to global bounds
                    validPeaks++;
                    for (int ii = i, j = 0; j < Gaussian2DFunction.PARAMETERS_PER_PEAK; ii++, j++) {
                        validParams[count++] = params[ii];
                    }
                }
                final double[] peakParams = extractParams(params, i);
                final double[] peakParamsDev = extractParams(paramsDev, i);
                addResult(bounds, regionBounds, peakParams, peakParamsDev, npoints, x, y, data[maxIndices[n]]);
                // Add fit result to the overlay - Coords are updated with the region offsets in addResult
                final double xf = peakParams[Gaussian2DFunction.X_POSITION];
                final double yf = peakParams[Gaussian2DFunction.Y_POSITION];
                xpoints[npoints] = (float) xf;
                ypoints[npoints] = (float) yf;
                npoints++;
            }
            setOverlay(npoints, xpoints, ypoints);
            // Draw the fit
            if (validPeaks != 0) {
                addToImage(bounds.x, bounds.y, renderedImage, validParams, validPeaks, width, height);
            }
        } else {
            if (isLogProgress()) {
                IJ.log("Failed to fit " + TextUtils.pleural(maxIndices.length, "peak") + ": " + getReason(fitResult));
            }
            imp.setOverlay(null);
        }
    } else {
        if (isLogProgress()) {
            IJ.log("Individual fit");
        }
        int npoints = 0;
        final float[] xpoints = new float[maxIndices.length];
        final float[] ypoints = new float[maxIndices.length];
        // Extract each peak and fit individually
        final ImageExtractor ie = ImageExtractor.wrap(data, width, height);
        float[] region = null;
        final Gaussian2DFitter gf = createGaussianFitter(settings.filterResults);
        double[] validParams = null;
        final ShortProcessor renderedImageCount = settings.showFit ? new ShortProcessor(ip.getWidth(), ip.getHeight()) : null;
        for (int n = 0; n < maxIndices.length; n++) {
            final int y = maxIndices[n] / width;
            final int x = maxIndices[n] % width;
            final long time = System.nanoTime();
            final Rectangle regionBounds = ie.getBoxRegionBounds(x, y, settings.singleRegionSize);
            region = ie.crop(regionBounds, region);
            final int newIndex = (y - regionBounds.y) * regionBounds.width + x - regionBounds.x;
            if (isLogProgress()) {
                IJ.log("Fitting peak " + (n + 1));
            }
            final double[] peakParams = fitSingle(gf, region, regionBounds.width, regionBounds.height, newIndex, smoothData[maxIndices[n]]);
            ellapsed += System.nanoTime() - time;
            // Output fit result
            if (peakParams != null) {
                if (settings.showFit) {
                    // Copy the valid parameters before there are adjusted to global bounds
                    validParams = peakParams.clone();
                }
                double[] peakParamsDev = null;
                if (settings.showDeviations) {
                    peakParamsDev = convertParameters(fitResult.getParameterDeviations());
                }
                addResult(bounds, regionBounds, peakParams, peakParamsDev, n, x, y, data[maxIndices[n]]);
                // Add fit result to the overlay - Coords are updated with the region offsets in addResult
                final double xf = peakParams[Gaussian2DFunction.X_POSITION];
                final double yf = peakParams[Gaussian2DFunction.Y_POSITION];
                xpoints[npoints] = (float) xf;
                ypoints[npoints] = (float) yf;
                npoints++;
                // Draw the fit
                if (settings.showDeviations) {
                    final int ox = bounds.x + regionBounds.x;
                    final int oy = bounds.y + regionBounds.y;
                    addToImage(ox, oy, renderedImage, validParams, 1, regionBounds.width, regionBounds.height);
                    addCount(ox, oy, renderedImageCount, regionBounds.width, regionBounds.height);
                }
            } else if (isLogProgress()) {
                IJ.log("Failed to fit peak " + (n + 1) + ": " + getReason(fitResult));
            }
        }
        // Update the overlay
        if (npoints > 0) {
            setOverlay(npoints, xpoints, ypoints);
        } else {
            imp.setOverlay(null);
        }
        // Create the mean
        if (settings.showFit) {
            for (int i = renderedImageCount.getPixelCount(); i-- > 0; ) {
                final int count = renderedImageCount.get(i);
                if (count > 1) {
                    renderedImage.setf(i, renderedImage.getf(i) / count);
                }
            }
        }
    }
    results.end();
    if (renderedImage != null) {
        ImageJUtils.display(TITLE, renderedImage);
    }
    if (isLogProgress()) {
        IJ.log("Time = " + (ellapsed / 1000000.0) + "ms");
    }
}
Also used : FloatProcessor(ij.process.FloatProcessor) Gaussian2DFitter(uk.ac.sussex.gdsc.smlm.fitting.Gaussian2DFitter) Rectangle(java.awt.Rectangle) ImageJTablePeakResults(uk.ac.sussex.gdsc.smlm.ij.results.ImageJTablePeakResults) ShortProcessor(ij.process.ShortProcessor) BlockMeanFilter(uk.ac.sussex.gdsc.smlm.filters.BlockMeanFilter) FitConfiguration(uk.ac.sussex.gdsc.smlm.engine.FitConfiguration) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) GenericDialog(ij.gui.GenericDialog) CalibrationWriter(uk.ac.sussex.gdsc.smlm.data.config.CalibrationWriter) ImageExtractor(uk.ac.sussex.gdsc.core.utils.ImageExtractor)

Example 18 with ShortProcessor

use of ij.process.ShortProcessor in project GDSC-SMLM by aherbert.

the class IJImagePeakResults method createNewProcessor.

private ImageProcessor createNewProcessor(int imageWidth, int imageHeight) {
    // Equalised display requires a 16-bit image to allow fast processing of the histogram 
    if ((displayFlags & DISPLAY_EQUALIZED) != 0) {
        pixels = new short[data.length];
        return new ShortProcessor(imageWidth, imageHeight, (short[]) pixels, null);
    } else {
        pixels = new float[data.length];
        // Zero is mapped to 0 in the LUT.
        if ((displayFlags & DISPLAY_MAPPED) != 0) {
            MappedFloatProcessor fp = new MappedFloatProcessor(imageWidth, imageHeight, (float[]) pixels, null);
            fp.setMapZero((displayFlags & DISPLAY_MAP_ZERO) != 0);
            return fp;
        }
        return new FloatProcessor(imageWidth, imageHeight, (float[]) pixels, null);
    }
}
Also used : MappedFloatProcessor(ij.process.MappedFloatProcessor) FloatProcessor(ij.process.FloatProcessor) MappedFloatProcessor(ij.process.MappedFloatProcessor) ShortProcessor(ij.process.ShortProcessor)

Example 19 with ShortProcessor

use of ij.process.ShortProcessor in project GDSC-SMLM by aherbert.

the class SplitResults method splitResults.

private void splitResults(MemoryPeakResults results, ImageProcessor ip) {
    IJ.showStatus("Splitting " + Utils.pleural(results.size(), "result"));
    // Create an object mask
    ObjectAnalyzer objectAnalyzer = new ObjectAnalyzer(ip, false);
    final int maxx = ip.getWidth();
    final int maxy = ip.getHeight();
    final float scaleX = (float) results.getBounds().width / maxx;
    final float scaleY = (float) results.getBounds().height / maxy;
    // Create a results set for each object
    final int maxObject = objectAnalyzer.getMaxObject();
    MemoryPeakResults[] resultsSet = new MemoryPeakResults[maxObject + 1];
    for (int object = 0; object <= maxObject; object++) {
        MemoryPeakResults newResults = new MemoryPeakResults();
        newResults.copySettings(results);
        newResults.setName(results.getName() + " " + object);
        resultsSet[object] = newResults;
    }
    final int[] mask = objectAnalyzer.getObjectMask();
    if (showObjectMask) {
        ImageProcessor objectIp = (maxObject <= 255) ? new ByteProcessor(maxx, maxy) : new ShortProcessor(maxx, maxy);
        for (int i = 0; i < mask.length; i++) objectIp.set(i, mask[i]);
        ImagePlus imp = Utils.display(objectMask + " Objects", objectIp);
        imp.setDisplayRange(0, maxObject);
        imp.updateAndDraw();
    }
    // Process the results mapping them to their objects
    int i = 0;
    final int size = results.size();
    final int step = Utils.getProgressInterval(size);
    for (PeakResult result : results.getResults()) {
        if (++i % step == 0)
            IJ.showProgress(i, size);
        // Map to the mask objects
        final int object;
        int x = (int) (result.getXPosition() / scaleX);
        int y = (int) (result.getYPosition() / scaleY);
        if (x < 0 || x >= maxx || y < 0 || y >= maxy) {
            object = 0;
        } else {
            final int index = y * maxx + x;
            if (index < 0 || index >= mask.length)
                object = 0;
            else
                object = mask[index];
        }
        resultsSet[object].add(result);
    }
    IJ.showProgress(1);
    // Add the new results sets to memory
    i = 0;
    for (int object = (nonMaskDataset) ? 0 : 1; object <= maxObject; object++) {
        if (!resultsSet[object].isEmpty()) {
            MemoryPeakResults.addResults(resultsSet[object]);
            i++;
        }
    }
    IJ.showStatus("Split " + Utils.pleural(results.size(), "result") + " into " + Utils.pleural(i, "set"));
}
Also used : ByteProcessor(ij.process.ByteProcessor) ImageProcessor(ij.process.ImageProcessor) ObjectAnalyzer(gdsc.smlm.ij.utils.ObjectAnalyzer) MemoryPeakResults(gdsc.smlm.results.MemoryPeakResults) ImagePlus(ij.ImagePlus) PeakResult(gdsc.smlm.results.PeakResult) ShortProcessor(ij.process.ShortProcessor)

Example 20 with ShortProcessor

use of ij.process.ShortProcessor in project bioformats by openmicroscopy.

the class Exporter method run.

// -- Exporter API methods --
/**
 * Executes the plugin.
 */
public void run() {
    String outfile = null;
    Boolean splitZ = null;
    Boolean splitC = null;
    Boolean splitT = null;
    Boolean padded = null;
    Boolean saveRoi = null;
    String compression = null;
    Boolean windowless = Boolean.FALSE;
    if (plugin.arg != null) {
        outfile = Macro.getValue(plugin.arg, "outfile", null);
        String z = Macro.getValue(plugin.arg, "splitZ", null);
        String c = Macro.getValue(plugin.arg, "splitC", null);
        String t = Macro.getValue(plugin.arg, "splitT", null);
        String zeroPad = Macro.getValue(plugin.arg, "padded", null);
        String sr = Macro.getValue(plugin.arg, "saveRoi", null);
        compression = Macro.getValue(plugin.arg, "compression", null);
        String id = Macro.getValue(plugin.arg, "imageid", null);
        splitZ = z == null ? null : Boolean.valueOf(z);
        splitC = c == null ? null : Boolean.valueOf(c);
        splitT = t == null ? null : Boolean.valueOf(t);
        padded = zeroPad == null ? null : Boolean.valueOf(zeroPad);
        saveRoi = sr == null ? null : Boolean.valueOf(sr);
        if (id != null) {
            try {
                int imageID = Integer.parseInt(id);
                ImagePlus plus = WindowManager.getImage(imageID);
                if (plus != null)
                    imp = plus;
            } catch (Exception e) {
            // nothing to do, we use the current imagePlus
            }
        }
        String w = Macro.getValue(plugin.arg, "windowless", null);
        if (w != null) {
            windowless = Boolean.valueOf(w);
        }
        plugin.arg = null;
    }
    if (outfile == null) {
        String options = Macro.getOptions();
        if (options != null) {
            String save = Macro.getValue(options, "save", null);
            if (save != null)
                outfile = save;
        }
    }
    // create a temporary file if window less
    if (windowless && (outfile == null || outfile.length() == 0)) {
        File tmp = null;
        try {
            String name = removeExtension(imp.getTitle());
            String n = name + ".ome.tif";
            tmp = File.createTempFile(name, ".ome.tif");
            File p = tmp.getParentFile();
            File[] list = p.listFiles();
            // make sure we delete a previous tmp file with same name if any
            if (list != null) {
                File toDelete = null;
                for (int i = 0; i < list.length; i++) {
                    if (list[i].getName().equals(n)) {
                        toDelete = list[i];
                        break;
                    }
                }
                if (toDelete != null) {
                    toDelete.delete();
                }
            }
            outfile = new File(p, n).getAbsolutePath();
            if (Recorder.record)
                Recorder.recordPath("outputfile", outfile);
            IJ.log("exporter outputfile " + outfile);
        } catch (Exception e) {
        // fall back to window mode.
        } finally {
            if (tmp != null)
                tmp.delete();
        }
    }
    File f = null;
    if (outfile == null || outfile.length() == 0) {
        // open a dialog prompting for the filename to save
        // NB: Copied and adapted from ij.io.SaveDIalog.jSaveDispatchThread,
        // so that the save dialog has a file filter for choosing output format.
        String dir = null, name = null;
        JFileChooser fc = GUITools.buildFileChooser(new ImageWriter(), false);
        fc.setDialogTitle("Bio-Formats Exporter");
        String defaultDir = OpenDialog.getDefaultDirectory();
        if (defaultDir != null)
            fc.setCurrentDirectory(new File(defaultDir));
        // set OME-TIFF as the default output format
        FileFilter[] ff = fc.getChoosableFileFilters();
        FileFilter defaultFilter = null;
        for (int i = 0; i < ff.length; i++) {
            if (ff[i] instanceof ExtensionFileFilter) {
                ExtensionFileFilter eff = (ExtensionFileFilter) ff[i];
                if (i == 0 || eff.getExtension().equals("ome.tif")) {
                    defaultFilter = eff;
                    break;
                }
            }
        }
        if (defaultFilter != null)
            fc.setFileFilter(defaultFilter);
        int returnVal = fc.showSaveDialog(IJ.getInstance());
        if (returnVal != JFileChooser.APPROVE_OPTION) {
            Macro.abort();
            return;
        }
        f = fc.getSelectedFile();
        dir = fc.getCurrentDirectory().getPath() + File.separator;
        name = fc.getName(f);
        if (f.exists()) {
            int ret = JOptionPane.showConfirmDialog(fc, "The file " + f.getName() + " already exists. \n" + "Would you like to replace it?", "Replace?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            if (ret != JOptionPane.OK_OPTION)
                f = null;
        } else {
            // ensure filename matches selected filter
            FileFilter filter = fc.getFileFilter();
            if (filter instanceof ExtensionFileFilter) {
                ExtensionFileFilter eff = (ExtensionFileFilter) filter;
                String[] ext = eff.getExtensions();
                String lName = name.toLowerCase();
                boolean hasExtension = false;
                for (int i = 0; i < ext.length; i++) {
                    if (lName.endsWith("." + ext[i])) {
                        hasExtension = true;
                        break;
                    }
                }
                if (!hasExtension && ext.length > 0) {
                    // append chosen extension
                    name = name + "." + ext[0];
                }
                f = fc.getSelectedFile();
                String filePath = f.getAbsolutePath();
                if (!filePath.endsWith("." + ext[0])) {
                    f = new File(filePath + '.' + ext[0]);
                }
                if (f.exists()) {
                    int ret1 = JOptionPane.showConfirmDialog(fc, "The file " + f.getName() + " already exists. \n" + "Would you like to replace it?", "Replace?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
                    if (ret1 != JOptionPane.OK_OPTION)
                        f = null;
                }
            }
        }
        if (f == null)
            Macro.abort();
        else {
            // do some ImageJ bookkeeping
            OpenDialog.setDefaultDirectory(dir);
            if (Recorder.record)
                Recorder.recordPath("save", dir + name);
        }
        if (dir == null || name == null)
            return;
        outfile = new File(dir, name).getAbsolutePath();
        if (outfile == null)
            return;
    }
    if (windowless) {
        if (splitZ == null)
            splitZ = Boolean.FALSE;
        if (splitC == null)
            splitC = Boolean.FALSE;
        if (splitT == null)
            splitT = Boolean.FALSE;
        if (padded == null)
            padded = Boolean.FALSE;
    }
    if (splitZ == null || splitC == null || splitT == null) {
        // ask if we want to export multiple files
        GenericDialog multiFile = new GenericDialog("Bio-Formats Exporter - Multiple Files");
        multiFile.addCheckbox("Write_each_Z_section to a separate file", false);
        multiFile.addCheckbox("Write_each_timepoint to a separate file", false);
        multiFile.addCheckbox("Write_each_channel to a separate file", false);
        multiFile.addCheckbox("Use zero padding for filename indexes", false);
        multiFile.showDialog();
        splitZ = multiFile.getNextBoolean();
        splitT = multiFile.getNextBoolean();
        splitC = multiFile.getNextBoolean();
        padded = multiFile.getNextBoolean();
        if (multiFile.wasCanceled())
            return;
    }
    try (IFormatWriter w = new ImageWriter().getWriter(outfile)) {
        int ptype = 0;
        int channels = 1;
        switch(imp.getType()) {
            case ImagePlus.GRAY8:
            case ImagePlus.COLOR_256:
                ptype = FormatTools.UINT8;
                break;
            case ImagePlus.COLOR_RGB:
                channels = 3;
                ptype = FormatTools.UINT8;
                break;
            case ImagePlus.GRAY16:
                ptype = FormatTools.UINT16;
                break;
            case ImagePlus.GRAY32:
                ptype = FormatTools.FLOAT;
                break;
        }
        String title = imp.getTitle();
        w.setWriteSequentially(true);
        FileInfo fi = imp.getOriginalFileInfo();
        String xml = fi == null ? null : fi.description == null ? null : fi.description.indexOf("xml") == -1 ? null : fi.description;
        OMEXMLService service = null;
        IMetadata store = null;
        try {
            ServiceFactory factory = new ServiceFactory();
            service = factory.getInstance(OMEXMLService.class);
            store = service.createOMEXMLMetadata(xml);
        } catch (DependencyException de) {
        } catch (ServiceException se) {
        }
        if (store == null)
            IJ.error("OME-XML Java library not found.");
        OMEXMLMetadataRoot root = (OMEXMLMetadataRoot) store.getRoot();
        if (root.sizeOfROIList() > 0) {
            while (root.sizeOfROIList() > 0) {
                ROI roi = root.getROI(0);
                root.removeROI(roi);
            }
            store.setRoot(root);
        }
        if (xml == null) {
            store.createRoot();
        } else if (store.getImageCount() > 1) {
            // the original dataset had multiple series
            // we need to modify the IMetadata to represent the correct series
            ArrayList<Integer> matchingSeries = new ArrayList<Integer>();
            for (int series = 0; series < store.getImageCount(); series++) {
                String type = store.getPixelsType(series).toString();
                int pixelType = FormatTools.pixelTypeFromString(type);
                if (pixelType == ptype) {
                    String imageName = store.getImageName(series);
                    if (title.indexOf(imageName) >= 0) {
                        matchingSeries.add(series);
                    }
                }
            }
            int series = 0;
            if (matchingSeries.size() > 1) {
                for (int i = 0; i < matchingSeries.size(); i++) {
                    int index = matchingSeries.get(i);
                    String name = store.getImageName(index);
                    boolean valid = true;
                    for (int j = 0; j < matchingSeries.size(); j++) {
                        if (i != j) {
                            String compName = store.getImageName(matchingSeries.get(j));
                            if (compName.indexOf(name) >= 0) {
                                valid = false;
                                break;
                            }
                        }
                    }
                    if (valid) {
                        series = index;
                        break;
                    }
                }
            } else if (matchingSeries.size() == 1)
                series = matchingSeries.get(0);
            ome.xml.model.Image exportImage = root.getImage(series);
            List<ome.xml.model.Image> allImages = root.copyImageList();
            for (ome.xml.model.Image img : allImages) {
                if (!img.equals(exportImage)) {
                    root.removeImage(img);
                }
            }
            store.setRoot(root);
        }
        store.setPixelsSizeX(new PositiveInteger(imp.getWidth()), 0);
        store.setPixelsSizeY(new PositiveInteger(imp.getHeight()), 0);
        store.setPixelsSizeZ(new PositiveInteger(imp.getNSlices()), 0);
        store.setPixelsSizeC(new PositiveInteger(channels * imp.getNChannels()), 0);
        store.setPixelsSizeT(new PositiveInteger(imp.getNFrames()), 0);
        if (store.getImageID(0) == null) {
            store.setImageID(MetadataTools.createLSID("Image", 0), 0);
        }
        if (store.getPixelsID(0) == null) {
            store.setPixelsID(MetadataTools.createLSID("Pixels", 0), 0);
        }
        // reset the pixel type, unless the only change is signedness
        // this prevents problems if the user changed the bit depth of the image
        boolean applyCalibrationFunction = false;
        try {
            int originalType = -1;
            if (store.getPixelsType(0) != null) {
                originalType = FormatTools.pixelTypeFromString(store.getPixelsType(0).toString());
            }
            if (ptype != originalType && (store.getPixelsType(0) == null || !FormatTools.isSigned(originalType) || FormatTools.getBytesPerPixel(originalType) != FormatTools.getBytesPerPixel(ptype))) {
                store.setPixelsType(PixelType.fromString(FormatTools.getPixelTypeString(ptype)), 0);
            } else if (FormatTools.isSigned(originalType)) {
                applyCalibrationFunction = true;
            }
        } catch (EnumerationException e) {
        }
        if (store.getPixelsBinDataCount(0) == 0 || store.getPixelsBinDataBigEndian(0, 0) == null) {
            store.setPixelsBinDataBigEndian(Boolean.FALSE, 0, 0);
        }
        if (store.getPixelsDimensionOrder(0) == null) {
            try {
                store.setPixelsDimensionOrder(DimensionOrder.fromString(ORDER), 0);
            } catch (EnumerationException e) {
            }
        }
        LUT[] luts = new LUT[imp.getNChannels()];
        for (int c = 0; c < imp.getNChannels(); c++) {
            if (c >= store.getChannelCount(0) || store.getChannelID(0, c) == null) {
                String lsid = MetadataTools.createLSID("Channel", 0, c);
                store.setChannelID(lsid, 0, c);
            }
            store.setChannelSamplesPerPixel(new PositiveInteger(channels), 0, 0);
            if (imp instanceof CompositeImage) {
                luts[c] = ((CompositeImage) imp).getChannelLut(c + 1);
            }
        }
        Calibration cal = imp.getCalibration();
        store.setPixelsPhysicalSizeX(FormatTools.getPhysicalSizeX(cal.pixelWidth), 0);
        store.setPixelsPhysicalSizeY(FormatTools.getPhysicalSizeY(cal.pixelHeight), 0);
        store.setPixelsPhysicalSizeZ(FormatTools.getPhysicalSizeZ(cal.pixelDepth), 0);
        store.setPixelsTimeIncrement(new Time(new Double(cal.frameInterval), UNITS.SECOND), 0);
        if (imp.getImageStackSize() != imp.getNChannels() * imp.getNSlices() * imp.getNFrames()) {
            if (!windowless) {
                IJ.showMessageWithCancel("Bio-Formats Exporter Warning", "The number of planes in the stack (" + imp.getImageStackSize() + ") does not match the number of expected planes (" + (imp.getNChannels() * imp.getNSlices() * imp.getNFrames()) + ")." + "\nIf you select 'OK', only " + imp.getImageStackSize() + " planes will be exported. If you wish to export all of the " + "planes,\nselect 'Cancel' and convert the Image5D window " + "to a stack.");
            }
            store.setPixelsSizeZ(new PositiveInteger(imp.getImageStackSize()), 0);
            store.setPixelsSizeC(new PositiveInteger(1), 0);
            store.setPixelsSizeT(new PositiveInteger(1), 0);
        }
        Object info = imp.getProperty("Info");
        if (info != null) {
            String imageInfo = info.toString();
            if (imageInfo != null) {
                String[] lines = imageInfo.split("\n");
                for (String line : lines) {
                    int eq = line.lastIndexOf("=");
                    if (eq > 0) {
                        String key = line.substring(0, eq).trim();
                        String value = line.substring(eq + 1).trim();
                        if (key.endsWith("BitsPerPixel")) {
                            w.setValidBitsPerPixel(Integer.parseInt(value));
                            break;
                        }
                    }
                }
            }
        }
        // NB: Animation rate code copied from ij.plugin.Animator#doOptions().
        final int rate;
        if (cal.fps != 0.0) {
            rate = (int) cal.fps;
        } else if (cal.frameInterval != 0.0 && cal.getTimeUnit().equals("sec")) {
            rate = (int) (1.0 / cal.frameInterval);
        } else {
            // NB: Code from ij.plugin.Animator#animationRate initializer.
            // The value is 7 by default in ImageJ, so must be 7 here as well.
            rate = (int) Prefs.getDouble(Prefs.FPS, 7.0);
        }
        if (rate > 0)
            w.setFramesPerSecond(rate);
        String[] outputFiles = new String[] { outfile };
        int sizeZ = store.getPixelsSizeZ(0).getValue();
        int sizeC = store.getPixelsSizeC(0).getValue();
        int sizeT = store.getPixelsSizeT(0).getValue();
        if (splitZ || splitC || splitT) {
            int nFiles = 1;
            if (splitZ) {
                nFiles *= sizeZ;
            }
            if (splitC) {
                nFiles *= sizeC;
            }
            if (splitT) {
                nFiles *= sizeT;
            }
            outputFiles = new String[nFiles];
            int dot = outfile.indexOf(".", outfile.lastIndexOf(File.separator));
            String base = outfile.substring(0, dot);
            String ext = outfile.substring(dot);
            int nextFile = 0;
            for (int z = 0; z < (splitZ ? sizeZ : 1); z++) {
                for (int c = 0; c < (splitC ? sizeC : 1); c++) {
                    for (int t = 0; t < (splitT ? sizeT : 1); t++) {
                        int index = FormatTools.getIndex(ORDER, sizeZ, sizeC, sizeT, sizeZ * sizeC * sizeT, z, c, t);
                        String pattern = base + (splitZ ? "_Z%z" : "") + (splitC ? "_C%c" : "") + (splitT ? "_T%t" : "") + ext;
                        outputFiles[nextFile++] = FormatTools.getFilename(0, index, store, pattern, padded);
                    }
                }
            }
        }
        if (!w.getFormat().startsWith("OME")) {
            if (splitZ) {
                store.setPixelsSizeZ(new PositiveInteger(1), 0);
            }
            if (splitC) {
                store.setPixelsSizeC(new PositiveInteger(1), 0);
            }
            if (splitT) {
                store.setPixelsSizeT(new PositiveInteger(1), 0);
            }
        }
        // prompt for options
        String[] codecs = w.getCompressionTypes();
        ImageProcessor proc = imp.getImageStack().getProcessor(1);
        Image firstImage = proc.createImage();
        firstImage = AWTImageTools.makeBuffered(firstImage, proc.getColorModel());
        int thisType = AWTImageTools.getPixelType((BufferedImage) firstImage);
        if (proc instanceof ColorProcessor) {
            thisType = FormatTools.UINT8;
        } else if (proc instanceof ShortProcessor) {
            thisType = FormatTools.UINT16;
        }
        boolean notSupportedType = !w.isSupportedType(thisType);
        if (notSupportedType) {
            IJ.error("Pixel type (" + FormatTools.getPixelTypeString(thisType) + ") not supported by this format.");
            return;
        }
        if (codecs != null && codecs.length > 1) {
            boolean selected = false;
            if (compression != null) {
                for (int i = 0; i < codecs.length; i++) {
                    if (codecs[i].equals(compression)) {
                        selected = true;
                        break;
                    }
                }
            }
            if (!selected && !windowless) {
                GenericDialog gd = new GenericDialog("Bio-Formats Exporter Options");
                gd.addChoice("Compression type: ", codecs, codecs[0]);
                if (saveRoi != null) {
                    gd.addCheckbox("Export ROIs", saveRoi.booleanValue());
                } else {
                    gd.addCheckbox("Export ROIs", true);
                }
                gd.showDialog();
                saveRoi = gd.getNextBoolean();
                if (gd.wasCanceled())
                    return;
                compression = gd.getNextChoice();
            }
        }
        boolean in = false;
        if (outputFiles.length > 1) {
            for (int i = 0; i < outputFiles.length; i++) {
                if (new File(outputFiles[i]).exists()) {
                    in = true;
                    break;
                }
            }
        }
        if (in && !windowless) {
            int ret1 = JOptionPane.showConfirmDialog(null, "Some files already exist. \n" + "Would you like to replace them?", "Replace?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            if (ret1 != JOptionPane.OK_OPTION) {
                return;
            }
            // Delete the files overwrite does not correctly work
            for (int i = 0; i < outputFiles.length; i++) {
                new File(outputFiles[i]).delete();
            }
        }
        // delete the file.
        if (f != null)
            f.delete();
        if (compression != null) {
            w.setCompression(compression);
        }
        // Save ROI's
        if (saveRoi != null && saveRoi.booleanValue()) {
            ROIHandler.saveROIs(store);
        }
        w.setMetadataRetrieve(store);
        // convert and save slices
        int size = imp.getImageStackSize();
        ImageStack is = imp.getImageStack();
        boolean doStack = w.canDoStacks() && size > 1;
        int start = doStack ? 0 : imp.getCurrentSlice() - 1;
        int end = doStack ? size : start + 1;
        boolean littleEndian = false;
        if (w.getMetadataRetrieve().getPixelsBigEndian(0) != null) {
            littleEndian = !w.getMetadataRetrieve().getPixelsBigEndian(0).booleanValue();
        } else if (w.getMetadataRetrieve().getPixelsBinDataCount(0) == 0) {
            littleEndian = !w.getMetadataRetrieve().getPixelsBinDataBigEndian(0, 0).booleanValue();
        }
        byte[] plane = null;
        w.setInterleaved(false);
        int[] no = new int[outputFiles.length];
        for (int i = start; i < end; i++) {
            if (doStack) {
                BF.status(false, "Saving plane " + (i + 1) + "/" + size);
                BF.progress(false, i, size);
            } else
                BF.status(false, "Saving image");
            proc = is.getProcessor(i + 1);
            if (proc instanceof RecordedImageProcessor) {
                proc = ((RecordedImageProcessor) proc).getChild();
            }
            int x = proc.getWidth();
            int y = proc.getHeight();
            if (proc instanceof ByteProcessor) {
                if (applyCalibrationFunction) {
                    // don't alter 'pixels' directly as that will
                    // affect the open ImagePlus
                    byte[] pixels = (byte[]) proc.getPixels();
                    plane = new byte[pixels.length];
                    float[] calibration = proc.getCalibrationTable();
                    for (int pixel = 0; pixel < pixels.length; pixel++) {
                        plane[pixel] = (byte) calibration[pixels[pixel] & 0xff];
                    }
                } else {
                    plane = (byte[]) proc.getPixels();
                }
            } else if (proc instanceof ShortProcessor) {
                short[] pixels = (short[]) proc.getPixels();
                if (applyCalibrationFunction) {
                    // don't alter 'pixels' directly as that will
                    // affect the open ImagePlus
                    plane = new byte[pixels.length * 2];
                    float[] calibration = proc.getCalibrationTable();
                    for (int pixel = 0; pixel < pixels.length; pixel++) {
                        short v = (short) calibration[pixels[pixel] & 0xffff];
                        DataTools.unpackBytes(v, plane, pixel * 2, 2, littleEndian);
                    }
                } else {
                    plane = DataTools.shortsToBytes(pixels, littleEndian);
                }
            } else if (proc instanceof FloatProcessor) {
                plane = DataTools.floatsToBytes((float[]) proc.getPixels(), littleEndian);
            } else if (proc instanceof ColorProcessor) {
                byte[][] pix = new byte[3][x * y];
                ((ColorProcessor) proc).getRGB(pix[0], pix[1], pix[2]);
                plane = new byte[3 * x * y];
                System.arraycopy(pix[0], 0, plane, 0, x * y);
                System.arraycopy(pix[1], 0, plane, x * y, x * y);
                System.arraycopy(pix[2], 0, plane, 2 * x * y, x * y);
                if (i == start) {
                    sizeC /= 3;
                }
            }
            int fileIndex = 0;
            if (doStack) {
                int[] coords = FormatTools.getZCTCoords(ORDER, sizeZ, sizeC, sizeT, size, i);
                int realZ = sizeZ;
                int realC = sizeC;
                int realT = sizeT;
                if (!splitZ) {
                    coords[0] = 0;
                    realZ = 1;
                }
                if (!splitC) {
                    coords[1] = 0;
                    realC = 1;
                }
                if (!splitT) {
                    coords[2] = 0;
                    realT = 1;
                }
                fileIndex = FormatTools.getIndex(ORDER, realZ, realC, realT, realZ * realC * realT, coords[0], coords[1], coords[2]);
            }
            if (notSupportedType) {
                IJ.error("Pixel type not supported by this format.");
            } else {
                w.changeOutputFile(outputFiles[fileIndex]);
                int currentChannel = FormatTools.getZCTCoords(ORDER, sizeZ, sizeC, sizeT, imp.getStackSize(), i)[1];
                if (luts[currentChannel] != null) {
                    // expand to 16-bit LUT if necessary
                    int bpp = FormatTools.getBytesPerPixel(thisType);
                    if (bpp == 1) {
                        w.setColorModel(luts[currentChannel]);
                    } else if (bpp == 2) {
                        int lutSize = luts[currentChannel].getMapSize();
                        byte[][] lut = new byte[3][lutSize];
                        luts[currentChannel].getReds(lut[0]);
                        luts[currentChannel].getGreens(lut[1]);
                        luts[currentChannel].getBlues(lut[2]);
                        short[][] newLut = new short[3][65536];
                        int bins = newLut[0].length / lut[0].length;
                        for (int c = 0; c < newLut.length; c++) {
                            for (int q = 0; q < newLut[c].length; q++) {
                                int index = q / bins;
                                newLut[c][q] = (short) ((lut[c][index] * lut[0].length) + (q % bins));
                            }
                        }
                        w.setColorModel(new Index16ColorModel(16, newLut[0].length, newLut, littleEndian));
                    }
                } else if (!proc.isDefaultLut()) {
                    w.setColorModel(proc.getColorModel());
                }
                w.saveBytes(no[fileIndex]++, plane);
            }
        }
        w.close();
    } catch (FormatException e) {
        WindowTools.reportException(e);
    } catch (IOException e) {
        WindowTools.reportException(e);
    }
}
Also used : ServiceFactory(loci.common.services.ServiceFactory) ArrayList(java.util.ArrayList) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) CompositeImage(ij.CompositeImage) OMEXMLService(loci.formats.services.OMEXMLService) Index16ColorModel(loci.formats.gui.Index16ColorModel) ImageProcessor(ij.process.ImageProcessor) RecordedImageProcessor(loci.plugins.util.RecordedImageProcessor) IMetadata(loci.formats.meta.IMetadata) FileInfo(ij.io.FileInfo) List(java.util.List) ArrayList(java.util.ArrayList) ImageStack(ij.ImageStack) FloatProcessor(ij.process.FloatProcessor) DependencyException(loci.common.services.DependencyException) ROI(ome.xml.model.ROI) FormatException(loci.formats.FormatException) IFormatWriter(loci.formats.IFormatWriter) JFileChooser(javax.swing.JFileChooser) ServiceException(loci.common.services.ServiceException) OMEXMLMetadataRoot(ome.xml.meta.OMEXMLMetadataRoot) File(java.io.File) ExtensionFileFilter(loci.formats.gui.ExtensionFileFilter) EnumerationException(ome.xml.model.enums.EnumerationException) ByteProcessor(ij.process.ByteProcessor) ImageWriter(loci.formats.ImageWriter) Time(ome.units.quantity.Time) ColorProcessor(ij.process.ColorProcessor) CompositeImage(ij.CompositeImage) GenericDialog(ij.gui.GenericDialog) RecordedImageProcessor(loci.plugins.util.RecordedImageProcessor) ExtensionFileFilter(loci.formats.gui.ExtensionFileFilter) FileFilter(javax.swing.filechooser.FileFilter) PositiveInteger(ome.xml.model.primitives.PositiveInteger) LUT(ij.process.LUT) Calibration(ij.measure.Calibration) IOException(java.io.IOException) ImagePlus(ij.ImagePlus) ServiceException(loci.common.services.ServiceException) DependencyException(loci.common.services.DependencyException) EnumerationException(ome.xml.model.enums.EnumerationException) FormatException(loci.formats.FormatException) IOException(java.io.IOException) ShortProcessor(ij.process.ShortProcessor) PositiveInteger(ome.xml.model.primitives.PositiveInteger)

Aggregations

ShortProcessor (ij.process.ShortProcessor)34 FloatProcessor (ij.process.FloatProcessor)20 ByteProcessor (ij.process.ByteProcessor)19 ImageProcessor (ij.process.ImageProcessor)10 ImagePlus (ij.ImagePlus)8 Point (java.awt.Point)8 Rectangle (java.awt.Rectangle)6 ArrayList (java.util.ArrayList)6 ImageStack (ij.ImageStack)4 ColorProcessor (ij.process.ColorProcessor)4 LUT (ij.process.LUT)3 Displayable (ini.trakem2.display.Displayable)3 Patch (ini.trakem2.display.Patch)3 FormatException (loci.formats.FormatException)3 ImageJ (ij.ImageJ)2 GenericDialog (ij.gui.GenericDialog)2 Calibration (ij.measure.Calibration)2 AffineTransform (java.awt.geom.AffineTransform)2 BufferedImage (java.awt.image.BufferedImage)2 File (java.io.File)2