3131import qupath .bioimageio .spec .tensor .axes .Axes ;
3232import qupath .bioimageio .spec .tensor .axes .SpaceAxes ;
3333import qupath .fx .dialogs .Dialogs ;
34- import qupath .fx .utils .GridPaneUtils ;
3534import qupath .lib .gui .QuPathGUI ;
3635import qupath .lib .images .ImageData ;
3736import qupath .lib .images .servers .ColorTransforms ;
3837import qupath .lib .images .servers .ImageServerMetadata ;
38+ import qupath .lib .images .servers .PixelCalibration ;
3939import qupath .lib .objects .classes .PathClass ;
4040import qupath .opencv .ml .BioimageIoTools ;
4141import qupath .opencv .ml .PatchClassifierParams ;
4242
43+
44+ import static qupath .fx .utils .FXUtils .resetSpinnerNullToPrevious ;
45+
46+
4347public 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 () {
0 commit comments