use of loci.plugins.util.VirtualImagePlus in project bioformats by openmicroscopy.
the class Colorizer method applyDisplayRanges.
// -- Helper methods --
private void applyDisplayRanges(ImagePlus imp, int series) {
if (imp instanceof VirtualImagePlus) {
// virtual stacks handle their own display ranges
return;
}
final ImporterOptions options = process.getOptions();
final ImageProcessorReader reader = process.getReader();
final int pixelType = reader.getPixelType();
final boolean autoscale = options.isAutoscale() || // always autoscale float data
FormatTools.isFloatingPoint(pixelType);
final int cSize = imp.getNChannels();
final double[] cMin = new double[cSize];
final double[] cMax = new double[cSize];
Arrays.fill(cMin, Double.NaN);
Arrays.fill(cMax, Double.NaN);
if (autoscale) {
// extract display ranges for autoscaling
final MinMaxCalculator minMaxCalc = process.getMinMaxCalculator();
final int cBegin = process.getCBegin(series);
final int cStep = process.getCStep(series);
for (int c = 0; c < cSize; c++) {
final int cIndex = cBegin + c * cStep;
Double cMinVal = null, cMaxVal = null;
try {
cMinVal = minMaxCalc.getChannelGlobalMinimum(cIndex);
cMaxVal = minMaxCalc.getChannelGlobalMaximum(cIndex);
if (cMinVal == null) {
cMinVal = minMaxCalc.getChannelKnownMinimum(cIndex);
}
if (cMaxVal == null) {
cMaxVal = minMaxCalc.getChannelKnownMaximum(cIndex);
}
} catch (FormatException exc) {
} catch (IOException exc) {
}
if (cMinVal != null)
cMin[c] = cMinVal;
if (cMaxVal != null)
cMax[c] = cMaxVal;
}
}
// for calibrated data, the offset from zero
final double zeroOffset = getZeroOffset(imp);
// fill in default display ranges as appropriate
final double min, max;
if (FormatTools.isFloatingPoint(pixelType)) {
// no defined min and max values for floating point data
min = max = Double.NaN;
} else {
final int bitDepth = reader.getBitsPerPixel();
final double halfPow = Math.pow(2, bitDepth - 1);
final double fullPow = 2 * halfPow;
final boolean signed = FormatTools.isSigned(pixelType);
if (signed) {
// signed data is centered at 0
min = -halfPow;
max = halfPow - 1;
} else {
// unsigned data begins at 0
min = 0;
max = fullPow - 1;
}
for (int c = 0; c < cSize; c++) {
if (Double.isNaN(cMin[c]))
cMin[c] = min;
if (Double.isNaN(cMax[c]))
cMax[c] = max;
}
}
// apply display ranges
if (imp instanceof CompositeImage) {
// apply channel display ranges
final CompositeImage compImage = (CompositeImage) imp;
for (int c = 0; c < cSize; c++) {
LUT lut = compImage.getChannelLut(c + 1);
// NB: Uncalibrate values before assigning to LUT min/max.
lut.min = cMin[c] - zeroOffset;
lut.max = cMax[c] - zeroOffset;
}
} else {
// compute global display range from channel display ranges
double globalMin = Double.POSITIVE_INFINITY;
double globalMax = Double.NEGATIVE_INFINITY;
for (int c = 0; c < cSize; c++) {
if (cMin[c] < globalMin)
globalMin = cMin[c];
if (cMax[c] > globalMax)
globalMax = cMax[c];
}
// NB: Uncalibrate values before assigning to display range min/max.
globalMin -= zeroOffset;
globalMax -= zeroOffset;
// apply global display range
ImageProcessor proc = imp.getProcessor();
if (proc instanceof ColorProcessor) {
// NB: Should never occur. ;-)
final ColorProcessor colorProc = (ColorProcessor) proc;
colorProc.setMinAndMax(globalMin, globalMax, 3);
} else {
ColorModel model = proc.getColorModel();
proc.setMinAndMax(globalMin, globalMax);
proc.setColorModel(model);
imp.setDisplayRange(globalMin, globalMax);
}
}
}
use of loci.plugins.util.VirtualImagePlus in project bioformats by openmicroscopy.
the class Colorizer method applyColors.
// -- Colorizer methods --
public List<ImagePlus> applyColors(List<ImagePlus> imps) {
final ImporterOptions options = process.getOptions();
final ImageProcessorReader reader = process.getReader();
final DimensionSwapper dimSwapper = process.getDimensionSwapper();
final ChannelFiller channelFiller = process.getChannelFiller();
final ImageReader imageReader = process.getImageReader();
for (int i = 0; i < imps.size(); i++) {
ImagePlus imp = imps.get(i);
final int series = (Integer) imp.getProperty(ImagePlusReader.PROP_SERIES);
reader.setSeries(series);
// get LUT for each channel
final String stackOrder = dimSwapper.getDimensionOrder();
final int zSize = imp.getNSlices();
final int cSize = imp.getNChannels();
final int tSize = imp.getNFrames();
final int stackSize = imp.getStackSize();
final LUT[] channelLUTs = new LUT[cSize];
boolean hasChannelLUT = false;
for (int c = 0; c < cSize; c++) {
final int index = FormatTools.getIndex(stackOrder, zSize, cSize, tSize, stackSize, 0, c, 0);
channelLUTs[c] = (LUT) imp.getProperty(ImagePlusReader.PROP_LUT + index);
if (channelLUTs[c] != null)
hasChannelLUT = true;
}
// compute color mode and LUTs to use
int mode = -1;
LUT[] luts;
if (options.isColorModeDefault()) {
// NB: Default color mode behavior depends on the situation.
final boolean isRGB = reader.isRGB() || imageReader.isRGB();
if (isRGB || channelFiller.isFilled()) {
// NB: The original data had more than one channel per plane
// (e.g., RGB image planes), so we use the composite display mode.
mode = CompositeImage.COMPOSITE;
// preserve original LUTs
luts = makeLUTs(channelLUTs, true);
} else if (hasChannelLUT) {
// NB: The original data had only one channel per plane,
// but had at least one lookup table defined. We use the color
// display mode, with missing LUTs as grayscale.
mode = CompositeImage.COLOR;
// preserve original LUTs
luts = makeLUTs(channelLUTs, true);
} else {
// NB: The original data had only one channel per plane,
// and had no lookup tables defined, so we use the grayscale mode.
mode = CompositeImage.GRAYSCALE;
luts = null;
}
} else if (options.isColorModeComposite()) {
mode = CompositeImage.COMPOSITE;
// preserve existing channel LUTs
luts = makeLUTs(channelLUTs, true);
} else if (options.isColorModeColorized()) {
mode = CompositeImage.COLOR;
// preserve existing channel LUTs
luts = makeLUTs(channelLUTs, true);
} else if (options.isColorModeGrayscale()) {
mode = CompositeImage.GRAYSCALE;
// use default (grayscale) channel LUTs
luts = null;
} else if (options.isColorModeCustom()) {
mode = CompositeImage.COLOR;
// override any existing channel LUTs
luts = makeLUTs(series);
} else {
throw new IllegalStateException("Invalid color mode: " + options.getColorMode());
}
// apply color mode and LUTs
final boolean doComposite = !options.isViewStandard() && mode != -1 && cSize > 1 && cSize <= 7;
if (doComposite) {
final ImagePlus toClose = imp;
CompositeImage compImage = new CompositeImage(imp, mode) {
@Override
public void close() {
super.close();
toClose.close();
}
@Override
public void show(String message) {
super.show(message);
// see ticket #12267
if (toClose instanceof VirtualImagePlus) {
int channel = getChannel();
double min = getDisplayRangeMin();
double max = getDisplayRangeMax();
for (int c = 0; c < cSize; c++) {
setPositionWithoutUpdate(c + 1, getSlice(), getFrame());
setDisplayRange(min, max);
}
reset();
setPosition(channel, getSlice(), getFrame());
}
}
};
compImage.setProperty(ImagePlusReader.PROP_SERIES, series);
if (luts != null)
compImage.setLuts(luts);
imps.set(i, compImage);
imp = compImage;
} else {
// NB: Cannot use CompositeImage for some reason.
if (luts != null && luts.length > 0 && luts[0] != null) {
if (imp instanceof VirtualImagePlus) {
((VirtualImagePlus) imp).setLUTs(luts);
} else if (cSize == 1)
imp.getProcessor().setColorModel(luts[0]);
}
if (mode != -1 && cSize > 7) {
// NB: Cannot use CompositeImage with more than seven channels.
BF.warn(options.isQuiet(), "Data has too many channels for " + options.getColorMode() + " color mode");
}
}
applyDisplayRanges(imp, series);
}
return imps;
}
use of loci.plugins.util.VirtualImagePlus in project bioformats by openmicroscopy.
the class ImagePlusReader method readImage.
private ImagePlus readImage(int s, boolean thumbnail) throws FormatException, IOException {
final ImporterOptions options = process.getOptions();
final int zCount = process.getZCount(s);
final int cCount = process.getCCount(s);
final int tCount = process.getTCount(s);
final List<LUT> luts = new ArrayList<LUT>();
// create image stack
final ImageStack stack;
if (options.isVirtual())
stack = createVirtualStack(process, s, luts);
else
stack = readPlanes(process, s, luts, thumbnail);
notifyListeners(new StatusEvent(1, 1, "Creating image"));
// create title
final String seriesName = process.getOMEMetadata().getImageName(s);
final String file = process.getCurrentFile();
final IFormatReader reader = process.getReader();
final String title = constructImageTitle(reader, file, seriesName, options.isGroupFiles());
// create image
final ImagePlus imp;
if (stack.isVirtual()) {
VirtualImagePlus vip = new VirtualImagePlus(title, stack);
vip.setReader(reader);
imp = vip;
saveLUTs(imp, luts);
} else
imp = createImage(title, stack, luts);
// if concatenating images only store metadata on first series
if (!options.isConcatenate() || s == 0) {
final String metadata = process.getOriginalMetadata().toString();
imp.setProperty("Info", metadata);
}
imp.setProperty(PROP_SERIES, s);
// retrieve the spatial calibration information, if available
final FileInfo fi = createFileInfo();
new Calibrator(process).applyCalibration(imp);
imp.setFileInfo(fi);
imp.setDimensions(cCount, zCount, tCount);
// open as a hyperstack, as appropriate
final boolean hyper = !options.isViewStandard();
imp.setOpenAsHyperStack(hyper);
return imp;
}
use of loci.plugins.util.VirtualImagePlus in project bioformats by openmicroscopy.
the class Slicer method reslice.
// -- Slicer methods --
public ImagePlus[] reslice(ImagePlus imp, boolean sliceC, boolean sliceZ, boolean sliceT, String stackOrder) {
ImageStack stack = imp.getImageStack();
boolean hyperstack = imp.isHyperStack();
Calibration calibration = imp.getCalibration();
int sizeZ = imp.getNSlices();
int sizeC = imp.getNChannels();
int sizeT = imp.getNFrames();
int slicesPerStack = stack.getSize();
if (sliceZ)
slicesPerStack /= sizeZ;
if (sliceC)
slicesPerStack /= sizeC;
if (sliceT)
slicesPerStack /= sizeT;
int realSizeZ = sliceZ ? 1 : sizeZ;
int realSizeC = sliceC ? 1 : sizeC;
int realSizeT = sliceT ? 1 : sizeT;
BFVirtualStack virtualStack = null;
if (stack instanceof BFVirtualStack) {
virtualStack = (BFVirtualStack) stack;
}
ImageStack[] newStacks = new ImageStack[stack.getSize() / slicesPerStack];
for (int i = 0; i < newStacks.length; i++) {
newStacks[i] = makeStack(stack);
if (newStacks[i] == null)
return null;
}
int stackZ = sliceZ ? sizeZ : 1;
int stackC = sliceC ? sizeC : 1;
int stackT = sliceT ? sizeT : 1;
int[][] planeIndexes = new int[newStacks.length][slicesPerStack];
for (int i = 0; i < sizeZ * sizeC * sizeT; i++) {
int[] zct = FormatTools.getZCTCoords(stackOrder, sizeZ, sizeC, sizeT, stack.getSize(), i);
int stackNdx = FormatTools.getIndex(stackOrder, stackZ, stackC, stackT, newStacks.length, sliceZ ? zct[0] : 0, sliceC ? zct[1] : 0, sliceT ? zct[2] : 0);
String label = stack.getSliceLabel(i + 1);
if (virtualStack != null) {
((BFVirtualStack) newStacks[stackNdx]).addSlice(label);
int sliceNdx = FormatTools.getIndex(stackOrder, realSizeZ, realSizeC, realSizeT, slicesPerStack, sliceZ ? 0 : zct[0], sliceC ? 0 : zct[1], sliceT ? 0 : zct[2]);
planeIndexes[stackNdx][sliceNdx] = i;
} else {
newStacks[stackNdx].addSlice(label, stack.getProcessor(i + 1));
}
}
ImagePlus[] newImps = new ImagePlus[newStacks.length];
for (int i = 0; i < newStacks.length; i++) {
if (virtualStack != null) {
((BFVirtualStack) newStacks[i]).setPlaneIndexes(planeIndexes[i]);
}
int[] zct = FormatTools.getZCTCoords(stackOrder, stackZ, stackC, stackT, newStacks.length, i);
if (imp.isComposite()) {
CompositeImage composite = (CompositeImage) imp;
if (composite.getMode() == CompositeImage.COLOR) {
LUT lut = composite.getChannelLut(zct[1] + 1);
newStacks[i].setColorModel(lut);
}
}
String title = imp.getTitle();
title += " -";
if (sliceZ)
title += " Z=" + zct[0];
if (sliceT)
title += " T=" + zct[2];
if (sliceC)
title += " C=" + zct[1];
ImagePlus p = null;
if (virtualStack != null) {
p = new VirtualImagePlus(title, newStacks[i]);
((VirtualImagePlus) p).setReader(virtualStack.getReader());
} else {
p = new ImagePlus(title, newStacks[i]);
}
p.setProperty(ImagePlusReader.PROP_SERIES, imp.getProperty(ImagePlusReader.PROP_SERIES));
p.setProperty("Info", imp.getProperty("Info"));
p.setDimensions(realSizeC, realSizeZ, realSizeT);
p.setCalibration(calibration);
p.setFileInfo(imp.getOriginalFileInfo());
if (!p.isComposite()) {
p.setOpenAsHyperStack(hyperstack);
}
if (imp.isComposite() && !sliceC) {
p = reorder(p, stackOrder, "XYCZT");
int mode = ((CompositeImage) imp).getMode();
newImps[i] = new CompositeImage(p, mode);
} else
newImps[i] = p;
double max = imp.getDisplayRangeMax();
double min = imp.getDisplayRangeMin();
newImps[i].setDisplayRange(min, max);
if (imp.isComposite() && newImps[i].isComposite()) {
for (int c = 1; c < newImps[i].getNChannels(); c++) {
LUT originalLut = ((CompositeImage) imp).getChannelLut(c);
LUT lut = ((CompositeImage) newImps[i]).getChannelLut(c);
lut.min = originalLut.min;
lut.max = originalLut.max;
}
}
}
return newImps;
}
Aggregations