private ImageStack loadImages() { String fileNameNumberRef = new String(); String fileNameNumberCorr = new String(); if (numOfIteration < 9) { fileNameNumberRef = "000" + numOfIteration; fileNameNumberCorr = "000" + (numOfIteration + 1); } if (numOfIteration == 9) { fileNameNumberRef = "0009"; fileNameNumberCorr = "0010"; } if (numOfIteration >= 10 && numOfIteration < 99) { fileNameNumberRef = "00" + numOfIteration; fileNameNumberCorr = "00" + (numOfIteration + 1); } if (numOfIteration == 99) { fileNameNumberRef = "0099"; fileNameNumberCorr = "0100"; } if (numOfIteration >= 100 && numOfIteration < 999) { fileNameNumberRef = "0" + numOfIteration; fileNameNumberCorr = "0" + (numOfIteration + 1); } if (numOfIteration == 999) { fileNameNumberRef = "0999"; fileNameNumberCorr = "1000"; } if (numOfIteration >= 1000) { fileNameNumberRef = String.valueOf(numOfIteration); fileNameNumberCorr = String.valueOf(numOfIteration + 1); } ImagePlus ref = new ImagePlus(dir + name + fileNameNumberRef + format); ImagePlus corr = new ImagePlus(dir + name + (fileNameNumberCorr) + format); ImageStack tmp = ImageStack.create(ref.getWidth(), ref.getHeight(), 2, ref.getBitDepth()); tmp.setPixels(ref.getProcessor().getPixels(), 1); tmp.setPixels(corr.getProcessor().getPixels(), 2); return tmp; }
/** * Resizes the current array to the given dimensions. * * @param input the array to resize * @param lenX the desired length in x-direction (with, horizontal length) * @param lenY the desired length in y-direction (height, vertical length) * @return a new 2d float array with the specified dimensions, and values interpolated from the * input array. */ public static float[][] resize(float[][] input, int lenX, int lenY) { float[] linearized = linearize2DArray(input); ImageStack is = ImageStack.create(input.length, input[0].length, 1, 32); is.setPixels(linearized, 1); ImageProcessor ip = new ImagePlus("", is).getProcessor(); ip.setInterpolationMethod(ImageProcessor.BICUBIC); float[] resized = (float[]) ip.resize(lenX, lenY).getPixels(); return linearizedArrayTo2D(resized, lenX, lenY); }
/** Splits the specified image into separate channels. */ public static ImagePlus[] split(ImagePlus imp) { if (imp.getType() == ImagePlus.COLOR_RGB) { ImageStack[] stacks = splitRGB(imp.getStack(), true); ImagePlus[] images = new ImagePlus[3]; images[0] = new ImagePlus("red", stacks[0]); images[1] = new ImagePlus("green", stacks[1]); images[2] = new ImagePlus("blue", stacks[2]); return images; } int width = imp.getWidth(); int height = imp.getHeight(); int channels = imp.getNChannels(); int slices = imp.getNSlices(); int frames = imp.getNFrames(); int bitDepth = imp.getBitDepth(); int size = slices * frames; Vector images = new Vector(); HyperStackReducer reducer = new HyperStackReducer(imp); for (int c = 1; c <= channels; c++) { ImageStack stack2 = new ImageStack(width, height, size); // create empty stack stack2.setPixels( imp.getProcessor().getPixels(), 1); // can't create ImagePlus will null 1st image ImagePlus imp2 = new ImagePlus("C" + c + "-" + imp.getTitle(), stack2); stack2.setPixels(null, 1); imp.setPosition(c, 1, 1); imp2.setDimensions(1, slices, frames); imp2.setCalibration(imp.getCalibration()); reducer.reduce(imp2); if (imp.isComposite() && ((CompositeImage) imp).getMode() == IJ.GRAYSCALE) IJ.run(imp2, "Grays", ""); if (imp2.getNDimensions() > 3) imp2.setOpenAsHyperStack(true); images.add(imp2); } ImagePlus[] array = new ImagePlus[images.size()]; return (ImagePlus[]) images.toArray(array); }
private ImagePlus findSurfaceVoxels(final ImagePlus imp) { final int w = imp.getWidth(); final int h = imp.getHeight(); final int d = imp.getImageStackSize(); final ImageStack stack = imp.getImageStack(); final ImageStack surfaceStack = new ImageStack(w, h, d); for (int z = 0; z < d; z++) { IJ.showStatus("Finding surface voxels"); final byte[] pixels = (byte[]) stack.getPixels(z + 1); surfaceStack.setPixels(pixels.clone(), z + 1); final ImageProcessor surfaceIP = surfaceStack.getProcessor(z + 1); for (int y = 0; y < h; y++) { checkNeighbours: for (int x = 0; x < w; x++) { if (getPixel(stack, x, y, z, w, h, d) == (byte) 0) continue; for (int nz = -1; nz < 2; nz++) { final int znz = z + nz; for (int ny = -1; ny < 2; ny++) { final int yny = y + ny; for (int nx = -1; nx < 2; nx++) { final int xnx = x + nx; final byte pixel = getPixel(stack, xnx, yny, znz, w, h, d); if (pixel == (byte) 0) continue checkNeighbours; } } } // we checked all the neighbours for a 0 // but didn't find one, so this is not a surface voxel surfaceIP.set(x, y, (byte) 1); } } } // turn all the 1's into 0's final int wh = w * h; for (int z = 0; z < d; z++) { IJ.showStatus("Finding surface voxels"); final ImageProcessor ip = surfaceStack.getProcessor(z + 1); for (int i = 0; i < wh; i++) { if (ip.get(i) == (byte) 1) ip.set(i, (byte) 0); } } final ImagePlus surfaceImp = new ImagePlus("Surface"); surfaceImp.setStack(surfaceStack); surfaceImp.setCalibration(imp.getCalibration()); return surfaceImp; }
/** * Combination of {@link ImageJInterpolation#crop(float[][], float, float, float, float)} and * {@link ImageJInterpolation#resize(float[][], int, int)}. Crops and resizes the input array into * a new output array. * * @param input the array to work on * @param lenX the desired length in x-direction (with, horizontal length) * @param lenY the desired length in y-direction (height, vertical length) * @param minX the lower index in x-direction * @param minY the lower index in y-direction * @param maxX the higher index in x-direction * @param maxY the higher index in y-direction * @return a new cropped and resized version of the input array */ public static float[][] cropAndResize( float[][] input, int lenX, int lenY, float minX, float minY, float maxX, float maxY) { float[] linearized = linearize2DArray(input); ImageStack is = ImageStack.create(input[0].length, input.length, 1, 32); is.setPixels(linearized, 1); ImageProcessor ip = new ImagePlus("", is).getProcessor(); ip.setInterpolationMethod(ImageProcessor.BICUBIC); ip.setRoi((int) minX, (int) minY, (int) Math.ceil(maxX - minX), (int) Math.ceil(maxY - minY)); float[] resized = (float[]) ip.crop().resize(lenX, lenY).getPixels(); return linearizedArrayTo2D(resized, lenX, lenY); }
/** * Makes a color {@link ImagePlus} from a color {@link Dataset}. The ImagePlus will have the same * X, Y, Z, & T dimensions. C will be 1. The data values and metadata are not assigned. Throws an * exception if the dataset is not color compatible. */ private ImagePlus makeColorImagePlus(final Dataset ds) { if (!LegacyUtils.isColorCompatible(ds)) { throw new IllegalArgumentException("Dataset is not color compatible"); } final int[] dimIndices = new int[5]; final int[] dimValues = new int[5]; LegacyUtils.getImagePlusDims(ds, dimIndices, dimValues); final int w = dimValues[0]; final int h = dimValues[1]; final int c = dimValues[2] / 3; final int z = dimValues[3]; final int t = dimValues[4]; final ImageStack stack = new ImageStack(w, h, c * z * t); for (int i = 0; i < c * z * t; i++) stack.setPixels(new int[w * h], i + 1); final ImagePlus imp = new ImagePlus(ds.getName(), stack); imp.setDimensions(c, z, t); return imp; }
/** Called by the PlugInFilterRunner to process the image or one frame of a stack */ public void run(ImageProcessor ip) { if (interrupted) return; int width = ip.getWidth(); int height = ip.getHeight(); int backgroundValue = (processType == VORONOI) ? (background255 ? 0 : (byte) 255) : // Voronoi needs EDM of the background (background255 ? (byte) 255 : 0); // all others do EDM of the foreground if (USES_WATERSHED[processType]) nPasses = 0; // watershed has its own progress bar FloatProcessor floatEdm = makeFloatEDM(ip, backgroundValue, false); ByteProcessor maxIp = null; if (USES_MAX_FINDER[processType]) { if (processType == VORONOI) floatEdm.multiply(-1); // Voronoi starts from minima of EDM int maxOutputType = USES_WATERSHED[processType] ? MaximumFinder.SEGMENTED : MaximumFinder.SINGLE_POINTS; boolean isEDM = processType != VORONOI; maxIp = maxFinder.findMaxima( floatEdm, MAXFINDER_TOLERANCE, ImageProcessor.NO_THRESHOLD, maxOutputType, false, isEDM); if (maxIp == null) { // segmentation cancelled by user? interrupted = true; return; } else if (processType != WATERSHED) { if (processType == VORONOI) floatEdm.multiply(-1); resetMasked(floatEdm, maxIp, processType == VORONOI ? -1 : 0); } } ImageProcessor outIp = null; if (processType == WATERSHED) { if (background255) maxIp.invert(); ip.copyBits(maxIp, 0, 0, Blitter.COPY); ip.setBinaryThreshold(); } else switch (outImageType) { // for all these, output contains the values of the EDM case FLOAT: outIp = floatEdm; break; case SHORT: floatEdm.setMinAndMax(0., 65535.); outIp = floatEdm.convertToShort(true); break; case BYTE: floatEdm.setMinAndMax(0., 255.); outIp = floatEdm.convertToByte(true); break; case BYTE_OVERWRITE: ip.setPixels(0, floatEdm); if (floatEdm.getMax() > 255.) ip.resetMinAndMax(); // otherwise we have max of floatEdm } if (outImageType != BYTE_OVERWRITE) { // new output image if (outStack == null) { outImp = new ImagePlus(TITLE_PREFIX[processType] + imp.getShortTitle(), outIp); } else outStack.setPixels(outIp.getPixels(), pfr.getSliceNumber()); } } // public void run
public void Calc_5Fr(ImagePlus imp1, ImagePlus imp2) { if (imp1.getType() != imp2.getType()) { error(); return; } if (imp1.getType() == 0) { // getType returns 0 for 8-bit, 1 for 16-bit bitDepth = "8-bit"; Prefs.set("ps.bitDepth", bitDepth); } else { bitDepth = "16-bit"; Prefs.set("ps.bitDepth", bitDepth); } int width = imp1.getWidth(); int height = imp1.getHeight(); if (width != imp2.getWidth() || height != imp2.getHeight()) { error(); return; } ImageStack stack1 = imp1.getStack(); // if (bgStackTitle != "NoBg") ImageStack stack2 = imp2.getStack(); ImageStack stack2 = imp2.getStack(); ImageProcessor ip = imp1.getProcessor(); int dimension = width * height; byte[] pixB; short[] pixS; float[][] pixF = new float[5][dimension]; float[][] pixFBg = new float[5][dimension]; float a; float b; float den; float aSmp; float bSmp; float denSmp; float aBg; float bBg; float denBg; float retF; float azimF; byte[] retB = new byte[dimension]; short[] retS = new short[dimension]; byte[] azimB = new byte[dimension]; short[] azimS = new short[dimension]; // Derived Variables: float swingAngle = 2f * (float) Math.PI * swing; float tanSwingAngleDiv2 = (float) Math.tan(swingAngle / 2.f); float tanSwingAngleDiv2DivSqrt2 = (float) (Math.tan(swingAngle / 2.f) / Math.sqrt(2)); float wavelengthDiv2Pi = wavelength / (2f * (float) Math.PI); // get the pixels of each slice in the stack and convert to float for (int i = 0; i < 5; i++) { if (bitDepth == "8-bit") { pixB = (byte[]) stack1.getPixels(i + 3); for (int j = 0; j < dimension; j++) pixF[i][j] = 0xff & pixB[j]; if (bgStackTitle != "NoBg") { pixB = (byte[]) stack2.getPixels(i + 3); for (int j = 0; j < dimension; j++) pixFBg[i][j] = 0xff & pixB[j]; } } else { pixS = (short[]) stack1.getPixels(i + 3); for (int j = 0; j < dimension; j++) pixF[i][j] = (float) pixS[j]; if (bgStackTitle != "NoBg") { pixS = (short[]) stack2.getPixels(i + 3); for (int j = 0; j < dimension; j++) pixFBg[i][j] = (float) pixS[j]; } } } // Algorithm // terms a and b for (int j = 0; j < dimension; j++) { denSmp = (pixF[1][j] + pixF[2][j] + pixF[3][j] + pixF[4][j] - 4 * pixF[0][j]) / 2; denBg = denSmp; a = (pixF[4][j] - pixF[1][j]); aSmp = a; aBg = a; b = (pixF[2][j] - pixF[3][j]); bSmp = b; bBg = b; if (bgStackTitle != "NoBg") { denBg = (pixFBg[1][j] + pixFBg[2][j] + pixFBg[3][j] + pixFBg[4][j] - 4 * pixFBg[0][j]) / 2; aBg = pixFBg[4][j] - pixFBg[1][j]; bBg = pixFBg[2][j] - pixFBg[3][j]; } // Special case of sample retardance half wave, denSmp = 0 if (denSmp == 0) { retF = (float) wavelength / 4; azimF = (float) (a == 0 & b == 0 ? 0 : (azimRef + 90 + 90 * Math.atan2(a, b) / Math.PI) % 180); } else { // Retardance, the background correction can be improved by separately considering sample // retardance values larger than a quarter wave if (bgStackTitle != "NoBg") { a = aSmp / denSmp - aBg / denBg; b = bSmp / denSmp - bBg / denBg; } else { a = aSmp / denSmp; b = bSmp / denSmp; } retF = (float) Math.atan(tanSwingAngleDiv2 * Math.sqrt(a * a + b * b)); if (denSmp < 0) retF = (float) Math.PI - retF; retF = retF * wavelengthDiv2Pi; // convert to nm if (retF > retCeiling) retF = retCeiling; // Orientation if ((bgStackTitle == "NoBg") || ((bgStackTitle != "NoBg") && (Math.abs(denSmp) < 1))) { a = aSmp; b = bSmp; } azimF = (float) (a == 0 & b == 0 ? 0 : (azimRef + 90 + 90 * Math.atan2(a, b) / Math.PI) % 180); } if (bitDepth == "8-bit") retB[j] = (byte) (((int) (255 * retF / retCeiling)) & 0xff); else retS[j] = (short) (4095 * retF / retCeiling); if (mirror == "Yes") azimF = 180 - azimF; if (bitDepth == "8-bit") azimB[j] = (byte) (((int) azimF) & 0xff); else azimS[j] = (short) (azimF * 10f); } // show the resulting images in slice 1 and 2 imp1.setSlice(3); if (bitDepth == "8-bit") { stack1.setPixels(retB, 1); stack1.setPixels(azimB, 2); } else { stack1.setPixels(retS, 1); stack1.setPixels(azimS, 2); } imp1.setSlice(1); IJ.selectWindow(imp1.getTitle()); Prefs.set("ps.sampleStackTitle", sampleStackTitle); Prefs.set("ps.bgStackTitle", bgStackTitle); Prefs.set("ps.mirror", mirror); Prefs.set("ps.wavelength", wavelength); Prefs.set("ps.swing", swing); Prefs.set("ps.retCeiling", retCeiling); Prefs.set("ps.azimRef", azimRef); Prefs.savePreferences(); }