use of qupath.lib.display.ChannelDisplayInfo in project qupath by qupath.
the class BrightnessContrastCommand method handleSliderChange.
void handleSliderChange() {
if (slidersUpdating)
return;
ChannelDisplayInfo infoVisible = getCurrentInfo();
if (infoVisible == null)
return;
double minValue = sliderMin.getValue();
double maxValue = sliderMax.getValue();
imageDisplay.setMinMaxDisplay(infoVisible, (float) minValue, (float) maxValue);
// Avoid displaying -0... which looks weird
if (Math.abs(Math.round(minValue * 100)) == 0)
minValue = 0;
if (Math.abs(Math.round(maxValue * 100)) == 0)
maxValue = 0;
// viewer.updateThumbnail();
viewer.repaintEntireImage();
// histogramPanel.setVerticalLines(new double[]{infoVisible.getMinDisplay(), infoVisible.getMaxDisplay()}, ColorToolsFX.TRANSLUCENT_BLACK_FX);
}
use of qupath.lib.display.ChannelDisplayInfo in project qupath by qupath.
the class BrightnessContrastCommand method updateHistogram.
private void updateHistogram() {
if (table == null || !isInitialized())
return;
ChannelDisplayInfo infoSelected = getCurrentInfo();
Histogram histogram = (imageDisplay == null || infoSelected == null) ? null : imageDisplay.getHistogram(infoSelected);
// histogram = histogramMap.get(infoSelected);
if (histogram == null) {
histogramPanel.getHistogramData().clear();
} else {
// Any animation is slightly nicer if we can modify the current data, rather than creating a new one
if (histogramPanel.getHistogramData().size() == 1) {
Color color = infoSelected.getColor() == null ? ColorToolsFX.TRANSLUCENT_BLACK_FX : ColorToolsFX.getCachedColor(infoSelected.getColor());
histogramPanel.getHistogramData().get(0).setHistogram(histogram, color);
} else {
HistogramData histogramData = HistogramPanelFX.createHistogramData(histogram, true, infoSelected.getColor());
histogramData.setNormalizeCounts(true);
histogramPanel.getHistogramData().setAll(histogramData);
}
}
NumberAxis xAxis = (NumberAxis) histogramPanel.getChart().getXAxis();
if (infoSelected != null && infoSelected.getMaxAllowed() == 255 && infoSelected.getMinAllowed() == 0) {
xAxis.setAutoRanging(false);
xAxis.setLowerBound(0);
xAxis.setUpperBound(255);
} else if (infoSelected != null) {
xAxis.setAutoRanging(false);
xAxis.setLowerBound(infoSelected.getMinAllowed());
xAxis.setUpperBound(infoSelected.getMaxAllowed());
// xAxis.setAutoRanging(true);
}
if (infoSelected != null)
xAxis.setTickUnit(infoSelected.getMaxAllowed() - infoSelected.getMinAllowed());
// Don't use the first of last count if it's an outlier
NumberAxis yAxis = (NumberAxis) histogramPanel.getChart().getYAxis();
if (infoSelected != null && histogram != null) {
long maxCount = 0L;
for (int i = 1; i < histogram.nBins() - 1; i++) maxCount = Math.max(maxCount, histogram.getCountsForBin(i));
if (maxCount == 0)
maxCount = histogram.getMaxCount();
yAxis.setAutoRanging(false);
yAxis.setLowerBound(0);
yAxis.setUpperBound((double) maxCount / histogram.getCountSum());
}
histogramPanel.getChart().getXAxis().setTickLabelsVisible(true);
histogramPanel.getChart().getXAxis().setLabel("Pixel value");
histogramPanel.getChart().getYAxis().setTickLabelsVisible(true);
// histogramPanel.getChart().getYAxis().setLabel("Frequency");
GridPane pane = new GridPane();
pane.setHgap(4);
pane.setVgap(2);
int r = 0;
if (histogram != null) {
pane.add(new Label("Min"), 0, r);
pane.add(new Label(df.format(histogram.getMinValue())), 1, r);
r++;
pane.add(new Label("Max"), 0, r);
pane.add(new Label(df.format(histogram.getMaxValue())), 1, r);
r++;
pane.add(new Label("Mean"), 0, r);
pane.add(new Label(df.format(histogram.getMeanValue())), 1, r);
r++;
pane.add(new Label("Std.dev"), 0, r);
pane.add(new Label(df.format(histogram.getStdDev())), 1, r);
r++;
}
chartTooltip.setGraphic(pane);
if (r == 0)
Tooltip.uninstall(histogramPanel.getChart(), chartTooltip);
else
Tooltip.install(histogramPanel.getChart(), chartTooltip);
}
use of qupath.lib.display.ChannelDisplayInfo in project qupath by qupath.
the class BrightnessContrastCommand method toggleTableSelectedChannels.
/**
* Request that channels currently selected (highlighted) in the table have their
* selected status inverted. This allows multiple channels to be turned on/off
* in one step.
*
* @see #setTableSelectedChannels(boolean)
*/
private void toggleTableSelectedChannels() {
if (!isInitialized())
return;
Set<ChannelDisplayInfo> selected = new HashSet<>(imageDisplay.selectedChannels());
for (ChannelDisplayInfo info : table.getSelectionModel().getSelectedItems()) {
imageDisplay.setChannelSelected(info, !selected.contains(info));
}
table.refresh();
if (viewer != null) {
// viewer.updateThumbnail();
viewer.repaintEntireImage();
}
}
use of qupath.lib.display.ChannelDisplayInfo in project qupath by qupath.
the class BrightnessContrastCommand method updateSliders.
private void updateSliders() {
if (!isInitialized())
return;
ChannelDisplayInfo infoVisible = getCurrentInfo();
if (infoVisible == null) {
sliderMin.setDisable(true);
sliderMax.setDisable(true);
return;
}
float range = infoVisible.getMaxAllowed() - infoVisible.getMinAllowed();
int n = (int) range;
boolean is8Bit = range == 255 && infoVisible.getMinAllowed() == 0 && infoVisible.getMaxAllowed() == 255;
if (is8Bit)
n = 256;
else if (n <= 20)
n = (int) (range / .001);
else if (n <= 200)
n = (int) (range / .01);
slidersUpdating = true;
double maxDisplay = Math.max(infoVisible.getMaxDisplay(), infoVisible.getMinDisplay());
double minDisplay = Math.min(infoVisible.getMaxDisplay(), infoVisible.getMinDisplay());
double minSlider = Math.min(infoVisible.getMinAllowed(), minDisplay);
double maxSlider = Math.max(infoVisible.getMaxAllowed(), maxDisplay);
sliderMin.setMin(minSlider);
sliderMin.setMax(maxSlider);
sliderMin.setValue(infoVisible.getMinDisplay());
sliderMax.setMin(minSlider);
sliderMax.setMax(maxSlider);
sliderMax.setValue(infoVisible.getMaxDisplay());
if (is8Bit) {
sliderMin.setMajorTickUnit(1);
sliderMax.setMajorTickUnit(1);
sliderMin.setMinorTickCount(n);
sliderMax.setMinorTickCount(n);
} else {
sliderMin.setMajorTickUnit(1);
sliderMax.setMajorTickUnit(1);
sliderMin.setMinorTickCount(n);
sliderMax.setMinorTickCount(n);
}
slidersUpdating = false;
sliderMin.setDisable(false);
sliderMax.setDisable(false);
chartWrapper.getThresholds().clear();
Color color = Color.rgb(0, 0, 0, 0.2);
chartWrapper.addThreshold(sliderMin.valueProperty(), color);
chartWrapper.addThreshold(sliderMax.valueProperty(), color);
chartWrapper.setIsInteractive(true);
// chartWrapper.getThresholds().setAll(sliderMin.valueProperty(), sliderMax.valueProperty());
// histogramPanel.setVerticalLines(new double[]{infoVisible.getMinDisplay(), infoVisible.getMaxDisplay()}, ColorToolsFX.TRANSLUCENT_BLACK_FX);
}
use of qupath.lib.display.ChannelDisplayInfo in project qupath by qupath.
the class ChannelDisplayTransformServer method readBufferedImage.
@Override
public BufferedImage readBufferedImage(final RegionRequest request) throws IOException {
// Transform the pixels, if required
BufferedImage img = getWrappedServer().readBufferedImage(request);
int width = img.getWidth();
int height = img.getHeight();
WritableRaster raster = null;
float[] pxFloat = null;
int b = 0;
for (ChannelDisplayInfo channel : channels) {
if (channel instanceof SingleChannelDisplayInfo) {
if (raster == null) {
SampleModel model = new BandedSampleModel(DataBuffer.TYPE_FLOAT, width, height, nChannels());
raster = Raster.createWritableRaster(model, null);
}
if (raster.getTransferType() == DataBuffer.TYPE_FLOAT) {
pxFloat = ((SingleChannelDisplayInfo) channel).getValues(img, 0, 0, width, height, pxFloat);
raster.setSamples(0, 0, width, height, b, pxFloat);
b++;
} else {
logger.error("Unable to apply color transform " + channel.getName() + " - incompatible with previously-applied transforms");
}
} else if (channels.size() == 1) {
int[] rgb = channel.getRGB(img, null, false);
img.setRGB(0, 0, width, height, rgb, 0, width);
return img;
} else {
logger.error("Cannot apply requested color transforms! Must either be a single RGB transform, or one or more single-channel transforms");
}
}
if (colorModel == null)
colorModel = ColorModelFactory.createColorModel(PixelType.FLOAT32, channels.size(), false, channels.stream().mapToInt(c -> {
Integer color = c.getColor();
if (color == null)
color = ColorTools.packRGB(255, 255, 255);
return color;
}).toArray());
return new BufferedImage(colorModel, raster, false, null);
}
Aggregations