use of qupath.lib.images.servers.ImageServerMetadata in project qupath by qupath.
the class CreateTrainingImageCommand method createSparseServer.
/**
* Create a {@link SparseImageServer} from a collection of images.
* @param entries project entries that may be added to the image
* @param predicate predicate used to select annotated regions
* @param maxWidth the preferred width of the generated image, in pixels (used to determine whether to append a region horizontally or vertically)
* @param doZ if true, take all slices of a z-stack for each region where available; if false, take the region and create a 2D image
* @return
* @throws IOException
*/
static SparseImageServer createSparseServer(Collection<ProjectImageEntry<BufferedImage>> entries, Predicate<PathObject> predicate, int maxWidth, boolean doZ) throws IOException {
var builder = new SparseImageServer.Builder();
boolean doT = false;
int pad = 0;
int x = 0;
int y = 0;
int rowHeight = 0;
ImageServerMetadata firstMetadata = null;
int n = 0;
for (var entry : entries) {
if (!entry.hasImageData())
continue;
var hierarchy = entry.readHierarchy();
if (hierarchy == null)
continue;
var annotations = hierarchy.getAnnotationObjects();
if (annotations.isEmpty())
continue;
try {
ImageServer<BufferedImage> server = null;
for (var annotation : annotations) {
if (!predicate.test(annotation))
continue;
var roi = annotation.getROI();
var region = ImageRegion.createInstance(roi);
if (server == null) {
server = entry.getServerBuilder().build();
if (firstMetadata == null)
firstMetadata = server.getMetadata();
else {
if (firstMetadata.getPixelType() != server.getPixelType()) {
logger.warn("Incompatible pixel types {} and {} - will skip regions from {}", server.getPixelType(), firstMetadata.getPixelType(), entry.getImageName());
break;
}
if (firstMetadata.getSizeC() != server.nChannels()) {
logger.warn("Incompatible channel counts {} and {} - will skip regions from {}", server.nChannels(), firstMetadata.getSizeC(), entry.getImageName());
break;
}
}
}
var croppedServer = new CroppedImageServer(server, region);
int[] zArray = doZ ? IntStream.range(0, croppedServer.nZSlices()).toArray() : new int[] { 0 };
int[] tArray = doT ? IntStream.range(0, croppedServer.nTimepoints()).toArray() : new int[] { 0 };
for (int t : tArray) {
for (int z : zArray) {
rowHeight = Math.max(region.getHeight(), rowHeight);
var regionOutput = ImageRegion.createInstance(x, y, region.getWidth(), region.getHeight(), z, t);
for (double downsample : croppedServer.getPreferredDownsamples()) {
builder.serverRegion(regionOutput, downsample, croppedServer);
n++;
}
}
}
// Increment x
x += region.getWidth() + pad;
// Move to next row
if (x >= maxWidth) {
y += rowHeight + pad;
rowHeight = 0;
x = 0;
}
}
} catch (Exception e) {
logger.warn("Exception trying to read {}: {}", entry.getImageName(), e.getLocalizedMessage());
}
}
if (n == 0) {
return null;
} else
return builder.build();
}
Aggregations