Skip to content

Commit

Permalink
rotation checks are now done recursively on all wrapped ImageServers
Browse files Browse the repository at this point in the history
  • Loading branch information
Carlo Castoldi committed Dec 6, 2024
1 parent 1d3b7f9 commit d22fd39
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 46 deletions.
28 changes: 11 additions & 17 deletions src/main/java/qupath/ext/biop/abba/AtlasImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
import qupath.ext.warpy.Warpy;
import qupath.imagej.tools.IJTools;
import qupath.lib.common.ColorTools;
import qupath.lib.gui.QuPathGUI;
import qupath.lib.images.ImageData;
import qupath.lib.images.servers.ImageServer;
import qupath.lib.images.servers.ImageServerBuilder;
import qupath.lib.images.servers.ImageServerMetadata;
import qupath.lib.images.servers.RotatedImageServer;
Expand All @@ -37,17 +35,20 @@
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static qupath.ext.biop.abba.AtlasTools.getLazyNestedBuilders;
import static qupath.ext.biop.abba.AtlasTools.getLazyRotation;

public class AtlasImporter {
private ImageData<BufferedImage> imageData;
private String atlasName;
Expand Down Expand Up @@ -228,21 +229,14 @@ public List<PathObject> getFlattenedWarpedAtlasRegions() {
rois.remove(right);

AffineTransform transform = null;

ImageServerBuilder.ServerBuilder<?> serverBuilder = imageData.getServerBuilder();
if (serverBuilder.getClass().getSimpleName().startsWith("Rotated")) {
for (ImageServerBuilder.ServerBuilder<?> serverBuilder: getLazyNestedBuilders(imageData)) {
// The roi will need to be transformed before being imported
// First : get the rotation
RotatedImageServer.Rotation rotation = null;
try {
Field rotationField = serverBuilder.getClass().getDeclaredField("rotation");
rotationField.setAccessible(true);
rotation = (RotatedImageServer.Rotation) rotationField.get(serverBuilder);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException("Unknown rotated ImageServerBuilder: "+serverBuilder.getClass());
}
Optional<RotatedImageServer.Rotation> rotation;
if ((rotation = getLazyRotation(serverBuilder)).isEmpty())
// the server is not rotated
continue;
ImageServerMetadata metadata = imageData.getServerMetadata();
switch (rotation) {
switch (rotation.get()) {
case ROTATE_NONE: // No rotation.
break;
case ROTATE_90: // Rotate 90 degrees clockwise.
Expand All @@ -258,7 +252,7 @@ public List<PathObject> getFlattenedWarpedAtlasRegions() {
transform.translate(-metadata.getHeight(), 0);
break;
default:
System.err.println("Unknown rotation for rotated image server: " + rotation);
System.err.println("Unknown rotation for rotated image server: " + rotation.get());
}
}

Expand Down
73 changes: 44 additions & 29 deletions src/main/java/qupath/ext/biop/abba/AtlasTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
import qupath.ext.warpy.Warpy;
import qupath.imagej.tools.IJTools;
import qupath.lib.common.ColorTools;
import qupath.lib.gui.QuPathGUI;
import qupath.lib.images.ImageData;
import qupath.lib.images.servers.ImageServer;
import qupath.lib.images.servers.ImageServerBuilder;
import qupath.lib.images.servers.ImageServerMetadata;
import qupath.lib.images.servers.RotatedImageServer;
Expand Down Expand Up @@ -45,6 +43,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -128,6 +127,35 @@ static PathObject getWarpedAtlasRegions(AtlasOntology ontology, ImageData<Buffer

}

static Optional<RotatedImageServer.Rotation> getLazyRotation(ImageServerBuilder.ServerBuilder<?> serverBuilder) {
try {
Field rotationField = serverBuilder.getClass().getDeclaredField("rotation");
rotationField.setAccessible(true);
return Optional.of((RotatedImageServer.Rotation) rotationField.get(serverBuilder));
} catch (NoSuchFieldException | IllegalAccessException e) {
return Optional.empty();
}
}

static Optional<ImageServerBuilder.ServerBuilder<?>> getLazyWrappedBuilder(ImageServerBuilder.ServerBuilder<?> serverBuilder) {
try {
Field builderField = serverBuilder.getClass().getDeclaredField("builder");
builderField.setAccessible(true);
return Optional.of((ImageServerBuilder.ServerBuilder<?>) builderField.get(serverBuilder));
} catch (NoSuchFieldException | IllegalAccessException e) {
return Optional.empty();
}
}

static List<ImageServerBuilder.ServerBuilder<?>> getLazyNestedBuilders(ImageData<?> imageData) {
Optional<? extends ImageServerBuilder.ServerBuilder<?>> serverBuilder = Optional.of(imageData.getServerBuilder());
List<ImageServerBuilder.ServerBuilder<?>> builders = new ArrayList<>();
do {
serverBuilder.ifPresent(builders::add);
} while ((serverBuilder = getLazyWrappedBuilder(serverBuilder.get())).isPresent());
return builders.reversed(); // the order is from the innermost server to the outermost
}

public static List<PathObject> getFlattenedWarpedAtlasRegions(AtlasOntology ontology, ImageData<BufferedImage> imageData, boolean splitLeftRight) {
Project<BufferedImage> project = QP.getProject();

Expand Down Expand Up @@ -162,20 +190,14 @@ public static List<PathObject> getFlattenedWarpedAtlasRegions(AtlasOntology onto


AffineTransform transform = null;
ImageServerBuilder.ServerBuilder<?> serverBuilder = imageData.getServerBuilder();
if (serverBuilder.getClass().getSimpleName().startsWith("Rotated")) {
for (ImageServerBuilder.ServerBuilder<?> serverBuilder: getLazyNestedBuilders(imageData)) {
// The roi will need to be transformed before being imported
// First : get the rotation
RotatedImageServer.Rotation rotation = null;
try {
Field rotationField = serverBuilder.getClass().getDeclaredField("rotation");
rotationField.setAccessible(true);
rotation = (RotatedImageServer.Rotation) rotationField.get(serverBuilder);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException("Unknown rotated ImageServerBuilder: "+serverBuilder.getClass());
}
Optional<RotatedImageServer.Rotation> rotation;
if ((rotation = getLazyRotation(serverBuilder)).isEmpty())
// the server is not rotated
continue;
ImageServerMetadata metadata = imageData.getServerMetadata();
switch (rotation) {
switch (rotation.get()) {
case ROTATE_NONE: // No rotation.
break;
case ROTATE_90: // Rotate 90 degrees clockwise.
Expand All @@ -191,7 +213,7 @@ public static List<PathObject> getFlattenedWarpedAtlasRegions(AtlasOntology onto
transform.translate(-metadata.getHeight(), 0);
break;
default:
System.err.println("Unknown rotation for rotated image server: " + rotation);
System.err.println("Unknown rotation for rotated image server: " + rotation.get());
}
}

Expand Down Expand Up @@ -365,21 +387,14 @@ public static RealTransform getAtlasToPixelTransform(ImageData<BufferedImage> im
RealTransform transformWithoutServerTransform = Warpy.getRealTransform(fTransform);

AffineTransform3D transform = new AffineTransform3D();

ImageServerBuilder.ServerBuilder<?> serverBuilder = imageData.getServerBuilder();
if (serverBuilder.getClass().getSimpleName().startsWith("Rotated")) {
for (ImageServerBuilder.ServerBuilder<?> serverBuilder: getLazyNestedBuilders(imageData)) {
// The roi will need to be transformed before being imported
// First : get the rotation
RotatedImageServer.Rotation rotation = null;
try {
Field rotationField = serverBuilder.getClass().getDeclaredField("rotation");
rotationField.setAccessible(true);
rotation = (RotatedImageServer.Rotation) rotationField.get(serverBuilder);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException("Unknown rotated ImageServerBuilder: "+serverBuilder.getClass());
}
Optional<RotatedImageServer.Rotation> rotation;
if ((rotation = getLazyRotation(serverBuilder)).isEmpty())
// the server is not rotated
continue;
ImageServerMetadata metadata = imageData.getServerMetadata();
switch (rotation) {
switch (rotation.get()) {
case ROTATE_NONE: // No rotation.
break;
case ROTATE_90:
Expand All @@ -406,7 +421,7 @@ public static RealTransform getAtlasToPixelTransform(ImageData<BufferedImage> im
});
break;
default:
System.err.println("Unknown rotation for rotated image server: " + rotation);
System.err.println("Unknown rotation for rotated image server: " + rotation.get());
}
}

Expand Down

0 comments on commit d22fd39

Please sign in to comment.