/** * Returns saturation corrected version of the input image. A simple, one-parametric * exponential-saturation function with characteristic saturation rate is used (see Greilich et * al., 2013; Klimpki et al., 2016) * * @param img Input image * @param dwell_time Pixel dwell time, unit has to match saturation_rate * @param saturation_rate Characteristic saturation rate, unit has to match dwell_time * @return */ public static ImagePlus saturationCorrection( ImagePlus img, double dwell_time, double saturation_rate) { boolean silent = (IJ.getInstance() == null); int nX = img.getWidth(); int nY = img.getHeight(); int nSlices = img.getNSlices(); int nFrames = img.getNFrames(); int nChannels = img.getNChannels(); ImageStack resIms = new ImageStack(nX, nY); FloatProcessor fp; ImageProcessor ip1; int total = nSlices * nFrames * nChannels; double prog = 0; if (silent) { System.out.println("SATURATION CORRECTION"); } else { IJ.showStatus("SATURATION CORRECTION"); } for (int i = 0; i < nChannels; i++) { for (int j = 0; j < nFrames; j++) { for (int k = 0; k < nSlices; k++) { if (silent) { FNTDprogress.updateProgress(prog / total); } else { IJ.showProgress(prog / total); } prog++; img.setPosition(i + 1, k + 1, j + 1); ip1 = img.getProcessor(); fp = new FloatProcessor(nX, nY); double count_rate; for (int m = 0; m < nX; m++) { for (int n = 0; n < nY; n++) { count_rate = ip1.getPixelValue(m, n); count_rate = 1.0 - count_rate / (dwell_time * saturation_rate); count_rate = -1.0 * saturation_rate * dwell_time * log(count_rate); fp.putPixelValue(m, n, count_rate); } } resIms.addSlice(fp); } } } FNTDprogress.updateProgress(1); System.out.println(""); ImagePlus resImp = new ImagePlus(img.getTitle() + " (sat. corrected)", resIms); if (resIms.getSize() > 1) { resImp = HyperStackConverter.toHyperStack( resImp, nChannels, nSlices, nFrames, "xyztc", "grayscale"); } return (resImp); }
/** * Returns image in units of adjusted count-rate (Klimpki et al., 2016), i.e. compensated for * laser power and dwell time. If requested, non-linearities in laser-power compensation are * considered. * * @param img Input image * @param dwell_time Pixel dwell time, unit will match rate (i.e. us --> MHz) * @param laser_power Percentage laser power, * @param laser_exponent Exponent of laser-power compensation non-linearity, referred to 10% * percentage laser power. Equals 0.0 for perfect linearity * @return */ public static ImagePlus getAdjustedCountrateImage( ImagePlus img, double dwell_time, double laser_power, double laser_exponent) { boolean silent = (IJ.getInstance() == null); int nX = img.getWidth(); int nY = img.getHeight(); int nSlices = img.getNSlices(); int nFrames = img.getNFrames(); int nChannels = img.getNChannels(); ImageStack resIms = new ImageStack(nX, nY); FloatProcessor fp; ImageProcessor ip1; int total = nSlices * nFrames * nChannels; double prog = 0; if (silent) { System.out.println("DWELL-TIME/LASER-POWER COMPENSATION"); } else { IJ.showStatus("DWELL-TIME/LASER-POWER COMPENSATION"); } for (int i = 0; i < nChannels; i++) { for (int j = 0; j < nFrames; j++) { for (int k = 0; k < nSlices; k++) { if (silent) { FNTDprogress.updateProgress(prog / total); } else { IJ.showProgress(prog / total); } prog++; img.setPosition(i + 1, k + 1, j + 1); ip1 = img.getProcessor(); fp = new FloatProcessor(nX, nY); double laser_factor = Math.pow(laser_power / 0.10, laser_exponent); for (int m = 0; m < nX; m++) { for (int n = 0; n < nY; n++) { fp.putPixelValue( m, n, ip1.getPixelValue(m, n) * laser_factor / (laser_power * dwell_time)); } } resIms.addSlice(fp); } } } FNTDprogress.updateProgress(1); System.out.println(""); ImagePlus resImp = new ImagePlus(img.getTitle() + " (adj. count-rate)", resIms); if (resIms.getSize() > 1) { resImp = HyperStackConverter.toHyperStack( resImp, nChannels, nSlices, nFrames, "xyztc", "grayscale"); } return (resImp); }
public static ImagePlus subtract(ImagePlus a, ImagePlus b) { boolean silent = (IJ.getInstance() == null); int nX = a.getWidth(); int nY = a.getHeight(); int nSlices = a.getNSlices(); int nFrames = a.getNFrames(); int nChannels = a.getNChannels(); if ((nX != b.getWidth()) || (nY != b.getHeight()) || (nSlices != b.getNSlices()) || (nFrames != b.getNFrames()) || (nChannels != b.getNChannels())) { if (silent) { System.out.println("Subtract: image dimensions do not match, return nothing."); } else { IJ.showMessage("Subtract: image dimensions do not match, return nothing."); } } ImageStack resIms = new ImageStack(nX, nY); FloatProcessor fp; ImageProcessor ip1, ip2; int total = nSlices * nFrames * nChannels; double prog = 0; if (silent) { System.out.println("SUBSTRACTING BACKGROUND"); } else { IJ.showStatus("SUBSTRACTING BACKGROUND"); } for (int i = 0; i < nChannels; i++) { for (int j = 0; j < nFrames; j++) { for (int k = 0; k < nSlices; k++) { if (silent) { FNTDprogress.updateProgress(prog / total); } else { IJ.showProgress(prog / total); } prog++; a.setPosition(i + 1, k + 1, j + 1); b.setPosition(i + 1, k + 1, j + 1); ip1 = a.getProcessor(); ip2 = b.getProcessor(); fp = new FloatProcessor(nX, nY); for (int m = 0; m < nX; m++) { for (int n = 0; n < nY; n++) { fp.putPixelValue(m, n, ip1.getPixelValue(m, n) - ip2.getPixelValue(m, n)); } } resIms.addSlice(fp); } } } FNTDprogress.updateProgress(1); System.out.println(""); ImagePlus resImp = new ImagePlus("Result of" + a.getTitle() + "-" + b.getTitle(), resIms); if (resIms.getSize() > 1) { resImp = HyperStackConverter.toHyperStack( resImp, nChannels, nSlices, nFrames, "xyztc", "grayscale"); } return (resImp); }