/** * Create a new stains object with the same StainVectors but new max (background) values. * * @param maxRed * @param maxGreen * @param maxBlue * @return */ public ColorDeconvolutionStains changeMaxValues(double maxRed, double maxGreen, double maxBlue) { return new ColorDeconvolutionStains(getName(), getStain(1), getStain(2), getStain(3), maxRed, maxGreen, maxBlue); }
public String getPrompt(final ImageData<?> imageData) { ColorDeconvolutionStains stains = imageData == null ? null : imageData.getColorDeconvolutionStains(); if (stains != null) { switch (this) { case STAIN_1: return stains.getStain(1).getName() + " (color deconvolved)"; case STAIN_2: return stains.getStain(2).getName() + " (color deconvolved)"; case STAIN_3: return stains.getStain(3).getName() + " (color deconvolved)"; default: break; } } return prompt; }
public String getName(final ColorDeconvolutionStains stains) { switch (this) { case STAIN_1: return stains == null ? "Stain 1" : stains.getStain(1).getName(); case STAIN_2: return stains == null ? "Stain 2" : stains.getStain(2).getName(); case STAIN_3: return stains == null ? "Stain 3" : stains.getStain(3).getName(); case HUE: return "Hue"; case OD: return "OD Sum"; default: return getPrompt(null); } }
/** * Get matrix inverse, as useful for color deconvolution. * See static ColorDeconvolution classes for usage. * * @return */ public double[][] getMatrixInverse() { // Create if we don't have one already if (matInverse == null) { double[][] stainMat = new double[][]{ getStain(1).getArray(), getStain(2).getArray(), getStain(3).getArray()}; ColorDeconvMatrix3x3 mat3x3 = new ColorDeconvMatrix3x3(stainMat); matInverse = mat3x3.inverse(); } return matInverse; }
public static String getColorDeconvolutionStainsAsString(final ColorDeconvolutionStains stains, final int nDecimalPlaces) { if (stains == null) return ""; StringBuilder sb = new StringBuilder(); sb.append("{"); sb.append("\"Name").append("\" : \"").append(stains.getName()).append("\", "); for (int i = 1; i <= 3; i++) { StainVector stain = stains.getStain(i); // No need to add the residual stain if (i == 3 && stain.isResidual()) continue; sb.append("\"Stain ").append(i).append("\" : \"").append(stain.getName()).append("\", "); sb.append("\"Values ").append(i).append("\" : \"").append(stain.arrayAsString(Locale.US, nDecimalPlaces)).append("\", "); } sb.append("\"Background\" : \""); sb.append(" ").append(GeneralTools.arrayToString(Locale.US, new double[]{stains.getMaxRed(), stains.getMaxGreen(), stains.getMaxBlue()}, nDecimalPlaces)); // sb.append(String.format( "%.Nf %.Nf %.Nf".replace("N", Integer.toString(nDecimalPlaces)), stains.getMaxRed(), stains.getMaxGreen(), stains.getMaxBlue())); // sb.append(stains.getMaxRed()).append(" "); // sb.append(stains.getMaxGreen()).append(" "); // sb.append(stains.getMaxBlue()); sb.append("\"}"); return sb.toString(); }
/** * Create a new ColorDeconvolutionStains object, with all settings the same except one of the stains has been changed. * If the third stain was a residual, it will also be regenerated (i.e. it won't remain the same residual... which would be wrong, * as it would be orthogonal to the old stain rather than the new one). * * @param stains * @param stain * @param stainNumber * @return */ public static ColorDeconvolutionStains makeModifiedStains(ColorDeconvolutionStains stains, StainVector stainNew, int stainNumber) { StainVector[] stainVectors = new StainVector[3]; stainVectors[0] = stains.getStain(1); stainVectors[1] = stains.getStain(2); stainVectors[2] = stains.getStain(3); stainVectors[stainNumber - 1] = stainNew; if (stainVectors[2].isResidual()) stainVectors[2] = null; return new ColorDeconvolutionStains(stains.getName(), stainVectors[0], stainVectors[1], stainVectors[2], stains.getMaxRed(), stains.getMaxGreen(), stains.getMaxBlue()); }
@Override public String getName() { ensureStainsUpdated(); if (method != null) return method.toString(); if (stains == null) return "Stain " + stainNumber + " (missing)"; return stains.getStain(stainNumber).getName(); }
public final void ensureStainsUpdated() { if (imageDisplay == null || imageDisplay.getImageData() == null) { stains = null; return; } stains = imageDisplay.getImageData().getColorDeconvolutionStains(); if (stainNumber < 0) { color = ColorTools.makeRGB(255, 255, 255); colorModel = ColorTransformerAWT.getDefaultColorModel(method); } else { color = stains.getStain(stainNumber).getColor(); colorModel = ColorToolsAwt.getIndexColorModel(stains.getStain(stainNumber)); } }
double s22 = matInv[2][2]; discardResidual = discardResidual && stainsInput.getStain(3).isResidual(); double d00 = stainsOutput.getStain(1).getRed(); double d01 = stainsOutput.getStain(1).getGreen(); double d02 = stainsOutput.getStain(1).getBlue(); double d10 = stainsOutput.getStain(2).getRed(); double d11 = stainsOutput.getStain(2).getGreen(); double d12 = stainsOutput.getStain(2).getBlue(); double d20 = stainsOutput.getStain(3).getRed(); double d21 = stainsOutput.getStain(3).getGreen(); double d22 = stainsOutput.getStain(3).getBlue();
StainVector s1 = new StainVector(stainsOriginal.getStain(1).getName(), red[ind1], green[ind1], blue[ind1]); StainVector s2 = new StainVector(stainsOriginal.getStain(2).getName(), red[ind2], green[ind2], blue[ind2]); s1 = new StainVector(stainsOriginal.getStain(1).getName(), red[ind2], green[ind2], blue[ind2]); s2 = new StainVector(stainsOriginal.getStain(2).getName(), red[ind1], green[ind1], blue[ind1]); double angle11 = StainVector.computeAngle(s1, stainsOriginal.getStain(1)); double angle12 = StainVector.computeAngle(s1, stainsOriginal.getStain(2)); double angle21 = StainVector.computeAngle(s2, stainsOriginal.getStain(1)); double angle22 = StainVector.computeAngle(s2, stainsOriginal.getStain(2)); if (Math.min(angle12, angle21) < Math.min(angle11, angle22)) { s1 = new StainVector(stainsOriginal.getStain(1).getName(), red[ind2], green[ind2], blue[ind2]); s2 = new StainVector(stainsOriginal.getStain(2).getName(), red[ind1], green[ind1], blue[ind1]);
double[] stain1 = stains.getStain(1).getArray(); double[] stain2 = stains.getStain(2).getArray(); float[] stain1Proj = new float[nnz]; float[] stain2Proj = new float[nnz]; StainVector stain2Refined = new StainVector(stains.getStain(2).getName(), base1[0]*cos + base2[0]*sin, base1[1]*cos + base2[1]*sin, base1[2]*cos + base2[2]*sin); cos = Math.cos(maxAngle); sin = Math.sin(maxAngle); StainVector stain1Refined = new StainVector(stains.getStain(1).getName(), base1[0]*cos + base2[0]*sin, base1[1]*cos + base2[1]*sin, base1[2]*cos + base2[2]*sin);
double rStain = stains.getStain(1).getRed(); double gStain = stains.getStain(1).getGreen(); double bStain = stains.getStain(1).getBlue(); od_lut_red = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); od_lut_green = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen()); rStain = stains.getStain(2).getRed(); gStain = stains.getStain(2).getGreen(); bStain = stains.getStain(2).getBlue(); od_lut_red = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); od_lut_green = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen()); rStain = stains.getStain(3).getRed(); gStain = stains.getStain(3).getGreen(); bStain = stains.getStain(3).getBlue(); od_lut_red = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); od_lut_green = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen()); rStain = stains.getStain(1).getRed(); gStain = stains.getStain(1).getGreen(); bStain = stains.getStain(1).getBlue(); od_lut_red = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); od_lut_green = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen()); rStain = stains.getStain(2).getRed(); gStain = stains.getStain(2).getGreen(); bStain = stains.getStain(2).getBlue(); od_lut_red = ColorDeconvolutionHelper.makeODLUT(stains.getMaxRed()); od_lut_green = ColorDeconvolutionHelper.makeODLUT(stains.getMaxGreen());