Skip to content

Commit 918415e

Browse files
Improve handling of pixel size (#17)
1 parent ec0f4b0 commit 918415e

5 files changed

Lines changed: 73 additions & 23 deletions

File tree

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55

66
qupathExtension {
77
name = "qupath-extension-bioimageio"
8-
version = "0.2.0-rc2"
8+
version = "0.2.0-rc3"
99
group = "io.github.qupath"
1010
description = "QuPath extension to use the Bioimage Model Zoo (bioimage.io)"
1111
automaticModule = "qupath.extension.bioimageio"

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pluginManagement {
88
}
99

1010
qupath {
11-
version = "0.7.1"
11+
version = "0.7.0"
1212
}
1313

1414
// Apply QuPath Gradle settings plugin to handle configuration

src/main/java/qupath/ext/bioimageio/BioimageIoPane.java

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,19 @@
3131
import qupath.bioimageio.spec.tensor.axes.Axes;
3232
import qupath.bioimageio.spec.tensor.axes.SpaceAxes;
3333
import qupath.fx.dialogs.Dialogs;
34-
import qupath.fx.utils.GridPaneUtils;
3534
import qupath.lib.gui.QuPathGUI;
3635
import qupath.lib.images.ImageData;
3736
import qupath.lib.images.servers.ColorTransforms;
3837
import qupath.lib.images.servers.ImageServerMetadata;
38+
import qupath.lib.images.servers.PixelCalibration;
3939
import qupath.lib.objects.classes.PathClass;
4040
import qupath.opencv.ml.BioimageIoTools;
4141
import qupath.opencv.ml.PatchClassifierParams;
4242

43+
44+
import static qupath.fx.utils.FXUtils.resetSpinnerNullToPrevious;
45+
46+
4347
public class BioimageIoPane extends BorderPane {
4448
private final QuPathGUI qupath;
4549
private static final Logger logger = LoggerFactory.getLogger(BioimageIoPane.class);
@@ -68,7 +72,15 @@ public class BioimageIoPane extends BorderPane {
6872
@FXML
6973
private Spinner<Double> pixelSizeSpinner;
7074
@FXML
75+
private Spinner<Double> downsampleSpinner;
76+
@FXML
7177
private Button imageJButton;
78+
@FXML
79+
private HBox downsampleBox;
80+
@FXML
81+
private HBox pixelSizeBox;
82+
@FXML
83+
private VBox resolutionSectionBox;
7284

7385
private BioimageIoCommand.BioimageIoTest tester;
7486

@@ -136,23 +148,37 @@ private void configurePixelSize(Model model) {
136148
String axString = Axes.getAxesString(axes);
137149
int xind = axString.indexOf("x");
138150
int yind = axString.indexOf("y");
139-
double xsize=0.25, ysize=0.25;
151+
double xsize=0, ysize=0;
152+
// if pixel size specified then use pixel size spinners
153+
PixelCalibration pixelCal = null;
140154
if (xind != -1 && yind != -1) {
141-
if (axes[xind] instanceof SpaceAxes.SpaceAxis spaceAxis) {
142-
if (spaceAxis.getUnit() != SpaceAxes.SpaceUnit.MICROMETER) {
143-
logger.warn("Unknown space unit {}", spaceAxis.getUnit());
155+
if (axes[xind] instanceof SpaceAxes.SpaceAxis spaceAxisX && axes[yind] instanceof SpaceAxes.SpaceAxis spaceAxisY) {
156+
if (spaceAxisX.getUnit() != SpaceAxes.SpaceUnit.MICROMETER || spaceAxisY.getUnit() != SpaceAxes.SpaceUnit.MICROMETER) {
157+
logger.warn("Unsupported space unit {}, ignoring", spaceAxisX.getUnit());
158+
pixelCal = PixelCalibration.getDefaultInstance();
159+
} else {
160+
xsize = spaceAxisX.getScale();
161+
ysize = spaceAxisY.getScale();
162+
pixelCal = new PixelCalibration.Builder().pixelSizeMicrons(xsize, ysize).build();
144163
}
145-
xsize = spaceAxis.getScale();
146-
}
147-
if (axes[yind] instanceof SpaceAxes.SpaceAxis spaceAxis) {
148-
if (spaceAxis.getUnit() != SpaceAxes.SpaceUnit.MICROMETER) {
149-
logger.warn("Unknown space unit {}", spaceAxis.getUnit());
150-
}
151-
ysize = spaceAxis.getScale();
164+
} else {
165+
logger.warn("X or Y axis is not a space axis and therefore has unknown pixel size");
152166
}
167+
} else {
168+
pixelCal = PixelCalibration.getDefaultInstance();
169+
}
170+
171+
// if pixel calibration is default, remove the pixel size box
172+
if (pixelCal == PixelCalibration.getDefaultInstance()) {
173+
resolutionSectionBox.getChildren().remove(pixelSizeBox);
174+
builder.inputResolution(PixelCalibration.getDefaultInstance(), 1);
175+
} else {
176+
// if using pixel size, we're not using downsample
177+
resolutionSectionBox.getChildren().remove(downsampleBox);
178+
double defaultValue = (xsize + ysize) / 2;
179+
pixelSizeSpinner.getValueFactory().setValue(defaultValue);
180+
builder.inputResolution(new PixelCalibration.Builder().pixelSizeMicrons(defaultValue, defaultValue).build());
153181
}
154-
double defaultValue = (xsize + ysize) / 2;
155-
pixelSizeSpinner.getValueFactory().setValue(defaultValue);
156182

157183
DecimalFormat format = new DecimalFormat("0.000");
158184
pixelSizeSpinner.getValueFactory().setConverter(new StringConverter<>() {
@@ -171,6 +197,16 @@ public Double fromString(String string) {
171197
}
172198
}
173199
});
200+
pixelSizeSpinner.valueProperty().addListener((v, o, n) -> {
201+
var pcBuilder = new PixelCalibration.Builder()
202+
.pixelSizeMicrons(n, n);
203+
builder.inputResolution(pcBuilder.build());
204+
});
205+
downsampleSpinner.valueProperty().addListener((v, o, n) -> {
206+
builder.inputResolution(PixelCalibration.getDefaultInstance(), n);
207+
});
208+
resetSpinnerNullToPrevious(downsampleSpinner);
209+
resetSpinnerNullToPrevious(pixelSizeSpinner);
174210
}
175211

176212
private void configureOutputClasses() {

src/main/resources/qupath/ext/bioimageio/bioimageio.fxml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,30 @@
2525
<Label text="%ui.section.input-channels" styleClass="bioimageio-subtitle"/>
2626
<VBox fx:id="inputChannelSelectors" />
2727
</VBox>
28-
<VBox >
28+
<VBox fx:id="resolutionSectionBox">
2929
<Label text="%ui.section.input-resolution" styleClass="bioimageio-subtitle"/>
30-
<HBox alignment="CENTER_LEFT" styleClass="standard-spacing">
31-
<Label text="%ui.section.input-resolution-description" wrapText="true"/>
32-
<Spinner fx:id="pixelSizeSpinner" prefWidth="100.0" >
30+
<HBox alignment="CENTER_LEFT" styleClass="standard-spacing" fx:id="pixelSizeBox">
31+
<Label text="%ui.section.input-pixel-size-description" wrapText="true"/>
32+
<Spinner fx:id="pixelSizeSpinner" editable="true" prefWidth="100.0" >
3333
<tooltip>
34-
<Tooltip text="%options.pixel-size" />
34+
<Tooltip text="%tooltip.options.pixel-size" />
3535
</tooltip>
3636
<valueFactory>
3737
<SpinnerValueFactory.DoubleSpinnerValueFactory min="0.01" max="5" initialValue="0.25" amountToStepBy="0.001"/>
3838
</valueFactory>
3939
</Spinner>
4040
</HBox>
41+
<HBox alignment="CENTER_LEFT" styleClass="standard-spacing" fx:id="downsampleBox">
42+
<Label text="%ui.section.input-downsample-description" wrapText="true"/>
43+
<Spinner fx:id="downsampleSpinner" editable="true" prefWidth="100.0" >
44+
<tooltip>
45+
<Tooltip text="%tooltip.options.downsample" />
46+
</tooltip>
47+
<valueFactory>
48+
<SpinnerValueFactory.DoubleSpinnerValueFactory min="0.01" max="100" initialValue="1" amountToStepBy="0.1"/>
49+
</valueFactory>
50+
</Spinner>
51+
</HBox>
4152
</VBox>
4253
<VBox fx:id="tileShapeOptionsBox">
4354
<Label text="%ui.section.input-tile-shape" styleClass="bioimageio-subtitle"/>

src/main/resources/qupath/ext/bioimageio/strings.properties

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ ui.section.input = Input
1010
ui.section.input-channels = Input channels
1111

1212
ui.section.input-resolution = Input resolution
13-
ui.section.input-resolution-description = Requested input pixel size
14-
options.pixel-size = The pixel size in microns at which the model will be applied
13+
ui.section.input-pixel-size-description = Requested input pixel size (microns)
14+
tooltip.options.pixel-size = The pixel size in microns at which the model will be applied
15+
16+
ui.section.input-downsample-description = Downsample factor
17+
tooltip.options.downsample = Downsample factor applied to input image before inference
1518

1619
ui.section.input-tile-shape = Input tile shape
1720
ui.options.input-tile-shape-fixed = Tile size fixed to [%d, %d]

0 commit comments

Comments
 (0)