/** * For originally-8-bit images, optical densities can usually be computed faster by preallocating a LUT with the 0-255 required values. * Otherwise, logs need to be calculated for every pixel (which can be relatively slow). * * @param px * @param maxValue * @param use8BitLUT */ public static void convertPixelsToOpticalDensities(float[] px, double maxValue, boolean use8BitLUT) { if (use8BitLUT) { double[] od_lut = makeODLUT(maxValue, 256); for (int i = 0; i < px.length; i++) px[i] = (float)makeODByLUT(px[i], od_lut); } else { for (int i = 0; i < px.length; i++) px[i] = (float)makeOD(px[i], maxValue); } }
/** * Convert red channel of packed rgb pixel to optical density values, using a specified maximum value. * * @param rgb * @param maxValue * @param px optional array used for output * @return */ public static float[] getBlueOpticalDensities(int[] rgb, double maxValue, float[] px) { if (px == null) px = new float[rgb.length]; double[] od_lut = makeODLUT(maxValue, 256); for (int i = 0; i < px.length; i++) px[i] = (float)makeODByLUT(ColorTools.blue(rgb[i]), od_lut); return px; }
double[] whiteValues = estimateWhiteValues(rgb); float[] redOD = ColorDeconvolutionHelper.getRedOpticalDensities(rgb, whiteValues[0], null); float[] greenOD = ColorDeconvolutionHelper.getGreenOpticalDensities(rgb, whiteValues[1], null); float[] blueOD = ColorDeconvolutionHelper.getBlueOpticalDensities(rgb, whiteValues[2], null); boolean[] mask = createStainMask(redOD, greenOD, blueOD, minStain, stains.isH_DAB() || stains.isH_E(), true, null);
public static ColorDeconvolutionStains estimateStains(final BufferedImage img, final ColorDeconvolutionStains stainsOriginal, final double minStain, final double maxStain, final double ignorePercentage, final boolean checkColors) { int[] buf = img.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth()); int[] rgb = buf; float[] red = ColorDeconvolutionHelper.getRedOpticalDensities(rgb, stainsOriginal.getMaxRed(), null); float[] green = ColorDeconvolutionHelper.getGreenOpticalDensities(rgb, stainsOriginal.getMaxGreen(), null); float[] blue = ColorDeconvolutionHelper.getBlueOpticalDensities(rgb, stainsOriginal.getMaxBlue(), null); return estimateStains(buf, red, green, blue, stainsOriginal, minStain, maxStain, ignorePercentage, checkColors); }
/** * Convert to optical densities in which a second image is used to provide the 'maximum' (i.e. white) pixel values. * @param px * @param pxMax */ public static void convertPixelsToOpticalDensities(float[] px, float[] pxMax) { for (int i = 0; i < px.length; i++) px[i] = (float)makeOD(px[i], pxMax[i]); }
protected static double[] makeODLUT(double maxValue) { return ColorDeconvolutionHelper.makeODLUT(maxValue, 256); }
public static final double makeODByLUT(double val, double[] OD_LUT) { return ColorDeconvolutionHelper.makeODByLUT((int)(val + .5), OD_LUT); }
/** * Determine median of RGB values. * The median of each channel is computed separately. * * @param name * @param rgb * @param redMax * @param greenMax * @param blueMax * @return */ public static int getMedianRGB(int[] rgb) { int n = rgb.length; // Extract medians for each channel int[] temp = new int[n]; for (int i = 0; i < rgb.length; i++) temp[i] = ColorTools.red(rgb[i]); int rMedian = getMedian(temp); for (int i = 0; i < rgb.length; i++) temp[i] = ColorTools.green(rgb[i]); int gMedian = getMedian(temp); for (int i = 0; i < rgb.length; i++) temp[i] = ColorTools.blue(rgb[i]); int bMedian = getMedian(temp); return ColorTools.makeRGB(rMedian, gMedian, bMedian); }
float[] green = ColorTransformer.getSimpleTransformedPixels(rgb, ColorTransformer.ColorTransformMethod.Green, null); float[] blue = ColorTransformer.getSimpleTransformedPixels(rgb, ColorTransformer.ColorTransformMethod.Blue, null); convertPixelsToOpticalDensities(red, redMax, n > 500); convertPixelsToOpticalDensities(green, greenMax, n > 500); //J convertPixelsToOpticalDensities(blue, blueMax, n > 500);
public static double[] makeODLUT(double maxValue, int nValues) { double[] OD_LUT = new double[nValues]; for (int i = 0; i < nValues; i++) //J OD_LUT[i] = makeOD(i, maxValue); return OD_LUT; }
/** * Convert red channel of packed rgb pixel to optical density values, using a specified maximum value. * * @param rgb * @param maxValue * @param px optional array used for output * @return */ public static float[] getGreenOpticalDensities(int[] rgb, double maxValue, float[] px) { if (px == null) px = new float[rgb.length]; double[] od_lut = makeODLUT(maxValue, 256); for (int i = 0; i < px.length; i++) px[i] = (float)makeODByLUT(ColorTools.green(rgb[i]), od_lut); return px; }
double[] od_lut_red = ColorDeconvolutionHelper.makeODLUT(maxRed); //J double[] od_lut_green = maxRed == maxGreen ? od_lut_red : ColorDeconvolutionHelper.makeODLUT(maxGreen); //J double[] od_lut_blue = maxBlue == maxRed ? od_lut_red : maxBlue == maxGreen ? od_lut_green : ColorDeconvolutionHelper.makeODLUT(maxBlue); //J
public static final double makeODByLUT(float val, double[] OD_LUT) { return ColorDeconvolutionHelper.makeODByLUT((int)(val + .5f), OD_LUT); }
public static float colorDeconvolveRGBPixel(int rgb, ColorDeconvolutionStains stains, int channel) { double[][] matInv = stains.getMatrixInverse(); double scaleRed = matInv[0][channel]; double scaleGreen = matInv[1][channel]; double scaleBlue = matInv[2][channel]; // Apply color deconvolution double r = ColorDeconvolutionHelper.makeOD((rgb & 0xff0000) >> 16, stains.getMaxRed()); double g = ColorDeconvolutionHelper.makeOD((rgb & 0xff00) >> 8, stains.getMaxGreen()); double b = ColorDeconvolutionHelper.makeOD((rgb & 0xff), stains.getMaxBlue()); return (float)(r * scaleRed + g * scaleGreen + b * scaleBlue); }
/** * Convert red channel of packed rgb pixel to optical density values, using a specified maximum value. * * @param rgb * @param maxValue * @param px optional array used for output * @return */ public static float[] getRedOpticalDensities(int[] rgb, double maxValue, float[] px) { if (px == null) px = new float[rgb.length]; double[] od_lut = makeODLUT(maxValue, 256); for (int i = 0; i < px.length; i++) px[i] = (float)makeODByLUT(ColorTools.red(rgb[i]), od_lut); return px; }
public static float[] colorDeconvolveRGBArray(int[] buf, double[] stain1, double[] stain2, double[] stain3, int channel, float[] output) { if (output == null || output.length != buf.length) output = new float[buf.length]; if (stain3 == null) stain3 = StainVector.cross3(stain1, stain2); double[][] stainMat = new double[][]{stain1, stain2, stain3}; ColorDeconvMatrix3x3 mat3x3 = new ColorDeconvMatrix3x3(stainMat); double[][] matInv = mat3x3.inverse(); double[] stain1Inv = matInv[0]; double[] stain2Inv = matInv[1]; double[] stain3Inv = matInv[2]; // Apply color deconvolution double[] od_lut = ColorDeconvolutionHelper.makeODLUT(255, 256); for (int i = 0; i < buf.length; i++) { int c = buf[i]; // Extract RGB values & convert to optical densities using a lookup table double r = od_lut[(c & 0xff0000) >> 16]; double g = od_lut[(c & 0xff00) >> 8]; double b = od_lut[c & 0xff]; // Apply deconvolution & store the results output[i] = (float)(r * stain1Inv[channel] + g * stain2Inv[channel] + b * stain3Inv[channel]); } return output; }
public static StainVector generateStainVectorFromRGB(String name, int rgb, double redMax, double greenMax, double blueMax) { double rOD = makeOD(ColorTools.red(rgb), redMax); double gOD = makeOD(ColorTools.green(rgb), greenMax); //J double bOD = makeOD(ColorTools.blue(rgb), blueMax); //J return new StainVector(name, rOD, gOD, bOD); }
od_lut = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); for (int i = 0; i < buf.length; i++) { pixels[i] = (float)od_lut[ColorTools.red(buf[i])]; od_lut = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen()); for (int i = 0; i < buf.length; i++) { pixels[i] = (float)od_lut[ColorTools.green(buf[i])]; od_lut = ColorDeconvolutionHelper.makeODLUT(stains.getMaxBlue()); for (int i = 0; i < buf.length; i++) { pixels[i] = (float)od_lut[ColorTools.blue(buf[i])]; od_lut_red = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); od_lut_green = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen()); od_lut_blue = ColorDeconvolutionHelper.makeODLUT(stains.getMaxBlue()); inverse = stains.getMatrixInverse(); for (int i = 0; i < buf.length; i++) { od_lut_red = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); od_lut_green = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen()); od_lut_blue = ColorDeconvolutionHelper.makeODLUT(stains.getMaxBlue()); inverse = stains.getMatrixInverse(); for (int i = 0; i < buf.length; i++) { od_lut_red = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); od_lut_green = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen()); od_lut_blue = ColorDeconvolutionHelper.makeODLUT(stains.getMaxBlue()); inverse = stains.getMatrixInverse(); for (int i = 0; i < buf.length; i++) {
@Override public float getValue(BufferedImage img, int x, int y) { ensureStainsUpdated(); if (stains == null) return 0f; int rgb = img.getRGB(x, y); if (method == null) return ColorDeconvolution.colorDeconvolveRGBPixel(rgb, stains, stainNumber-1); else if (method == ColorTransformMethod.Optical_density_sum) { int r = ColorTools.red(rgb); int g = ColorTools.green(rgb); int b = ColorTools.blue(rgb); return (float)(ColorDeconvolutionHelper.makeOD(r, stains.getMaxRed()) + ColorDeconvolutionHelper.makeOD(g, stains.getMaxGreen()) + ColorDeconvolutionHelper.makeOD(b, stains.getMaxBlue())); } else return ColorTransformer.getPixelValue(rgb, method); }