use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.
the class IJTools method extractHyperstack.
/**
* Extract a full ImageJ hyperstack for a specific region, for specified ranges of z-slices and time points.
*
* @param server server from which to extract pixels
* @param request region and downsample value; if null, the entire image is used
* @param zStart starting z-slice index (0-based index)
* @param zEnd ending z-slice index (exclusive)
* @param tStart starting timepoint index (0-based index)
* @param tEnd ending timepoint index (exclusive)
* @return the ImageJ hyperstack
* @throws IOException
*/
public static ImagePlus extractHyperstack(ImageServer<BufferedImage> server, RegionRequest request, int zStart, int zEnd, int tStart, int tEnd) throws IOException {
if (request == null)
request = RegionRequest.createInstance(server);
int nChannels = -1;
int nZ = zEnd - zStart;
int nT = tEnd - tStart;
double downsample = request.getDownsample();
ImageStack stack = null;
Calibration cal = null;
for (int t = tStart; t < tEnd; t++) {
for (int z = zStart; z < zEnd; z++) {
RegionRequest request2 = RegionRequest.createInstance(server.getPath(), downsample, request.getX(), request.getY(), request.getWidth(), request.getHeight(), z, t);
ImagePlus imp = IJTools.convertToImagePlus(server, request2).getImage();
if (stack == null) {
stack = new ImageStack(imp.getWidth(), imp.getHeight());
}
// Append to original image stack
for (int i = 1; i <= imp.getStack().getSize(); i++) {
stack.addSlice(imp.getStack().getSliceLabel(i), imp.getStack().getProcessor(i));
}
// Get the last calibration
cal = imp.getCalibration();
nChannels = imp.getNChannels();
}
}
PixelCalibration pixelCalibration = server.getPixelCalibration();
if (cal != null && !Double.isNaN(pixelCalibration.getZSpacingMicrons())) {
cal.pixelDepth = pixelCalibration.getZSpacingMicrons();
cal.setZUnit("um");
}
String name = ServerTools.getDisplayableImageName(server);
ImagePlus imp = new ImagePlus(name, stack);
CompositeImage impComp = null;
if (imp.getType() != ImagePlus.COLOR_RGB && nChannels > 1) {
impComp = new CompositeImage(imp, CompositeImage.COMPOSITE);
imp = impComp;
}
imp.setCalibration(cal);
imp.setDimensions(nChannels, nZ, nT);
// Set colors, if necesssary
if (impComp != null) {
for (int c = 0; c < nChannels; c++) {
impComp.setChannelLut(LUT.createLutFromColor(ColorToolsAwt.getCachedColor(server.getChannel(c).getColor())), c + 1);
}
}
return imp;
}
use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.
the class SLICSuperpixelsPlugin method getPreferredDownsample.
private static double getPreferredDownsample(final ImageData<BufferedImage> imageData, final ParameterList params) {
PixelCalibration cal = imageData.getServer().getPixelCalibration();
boolean hasPixelSizeMicrons = cal.hasPixelSizeMicrons();
double spacingPixels = hasPixelSizeMicrons ? params.getDoubleParameterValue("spacingMicrons") / cal.getAveragedPixelSizeMicrons() : params.getDoubleParameterValue("spacingPixels");
// We aim to have about PREFERRED_PIXEL_SPACING spacing, so need to downsample the image accordingly
double downsample = Math.max(1, Math.round(spacingPixels / PREFERRED_PIXEL_SPACING));
return downsample;
}
use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.
the class IJTools method estimateDownsampleFactor.
/**
* Estimate the downsample factor for an image region extracted from an image server, based upon
* the ratio of pixel sizes if possible or ratio of dimensions if necessary.
* <p>
* Note that the ratio of dimensions is only suitable if the full image has been extracted!
*
* @param imp
* @param server
* @return
*/
public static double estimateDownsampleFactor(final ImagePlus imp, final ImageServer<?> server) {
// Try to get the downsample factor from pixel size;
// if that doesn't work, resort to trying to get it from the image dimensions
double downsampleFactor;
Calibration cal = imp.getCalibration();
double xMicrons = IJTools.tryToParseMicrons(cal.pixelWidth, cal.getXUnit());
double yMicrons = IJTools.tryToParseMicrons(cal.pixelHeight, cal.getYUnit());
boolean ijHasMicrons = !Double.isNaN(xMicrons) && !Double.isNaN(yMicrons);
PixelCalibration pixelCalibration = server.getPixelCalibration();
if (pixelCalibration.hasPixelSizeMicrons() && ijHasMicrons) {
double downsampleX = xMicrons / pixelCalibration.getPixelWidthMicrons();
double downsampleY = yMicrons / pixelCalibration.getPixelHeightMicrons();
if (GeneralTools.almostTheSame(downsampleX, downsampleY, 0.001))
logger.debug("ImageJ downsample factor is being estimated from pixel sizes");
else
logger.warn("ImageJ downsample factor is being estimated from pixel sizes (and these don't seem to match! {} and {})", downsampleX, downsampleY);
downsampleFactor = (downsampleX + downsampleY) / 2.0;
} else {
double downsampleX = (double) server.getWidth() / imp.getWidth();
double downsampleY = (double) server.getHeight() / imp.getHeight();
if (GeneralTools.almostTheSame(downsampleX, downsampleY, 0.001))
logger.warn("ImageJ downsample factor is being estimated from image dimensions - assumes that ImagePlus corresponds to the full image server");
else
logger.warn("ImageJ downsample factor is being estimated from image dimensions - assumes that ImagePlus corresponds to the full image server (and these don't seem to match! {} and {})", downsampleX, downsampleY);
downsampleFactor = (downsampleX + downsampleY) / 2.0;
}
return downsampleFactor;
}
use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.
the class TestBioFormatsImageServer method printSummary.
/**
* Print a readable summary of an {@code ImageServer} along with some key metadata.
*
* @param server
*/
void printSummary(final ImageServer<?> server) {
PixelCalibration cal = server.getPixelCalibration();
logger.info(String.format("%s: %d x %d (c=%d, z=%d, t=%d), bpp=%d, mag=%.2f, downsamples=[%s], res=[%.4f,%.4f,%.4f]", server.getPath(), server.getWidth(), server.getHeight(), server.nChannels(), server.nZSlices(), server.nTimepoints(), server.getPixelType(), server.getMetadata().getMagnification(), GeneralTools.arrayToString(Locale.getDefault(Locale.Category.FORMAT), server.getPreferredDownsamples(), 4), cal.getPixelWidthMicrons(), cal.getPixelHeightMicrons(), cal.getZSpacingMicrons()));
}
use of qupath.lib.images.servers.PixelCalibration in project qupath by qupath.
the class TestBioFormatsImageServer method testProject.
void testProject(Project<BufferedImage> project) {
// We're not really testing Bio-Formats... and the messages can get in the way
DebugTools.enableIJLogging(false);
DebugTools.setRootLevel("error");
List<ProjectImageEntry<BufferedImage>> entries = project.getImageList();
System.out.println("Testing project with " + entries.size() + " entries: " + Project.getNameFromURI(project.getURI()));
for (ProjectImageEntry<BufferedImage> entry : entries) {
// String serverPath = entry.getServerPath();
// System.out.println("Opening: " + serverPath);
// String pathFile = BioFormatsImageServer.splitFilePathAndSeriesName(serverPath)[0];
// if (!new File(pathFile).exists()) {
// System.err.println("File does not exist for server path " + serverPath + " - will skip");
// }
BioFormatsImageServer server = null;
BufferedImage img = null;
BufferedImage imgThumbnail = null;
ImagePlus imp = null;
int tileSize = 256;
int z = 0;
int t = 0;
try {
// Create the server
server = (BioFormatsImageServer) entry.getServerBuilder().build();
// server = (BioFormatsImageServer)ImageServerProvider.buildServer(serverPath, BufferedImage.class, "--classname", BioFormatsServerBuilder.class.getName());
// Read a thumbnail
imgThumbnail = server.getDefaultThumbnail(server.nZSlices() / 2, 0);
// Read from the center of the image
int w = server.getWidth() < tileSize ? server.getWidth() : tileSize;
int h = server.getHeight() < tileSize ? server.getHeight() : tileSize;
z = (int) (server.nZSlices() / 2);
t = (int) (server.nTimepoints() / 2);
RegionRequest request = RegionRequest.createInstance(server.getPath(), 1, (server.getWidth() - w) / 2, (server.getHeight() - h) / 2, w, h, z, t);
img = server.readBufferedImage(request);
// (Skip if we have multiple series, as the setFlattenedResolutions() status can cause confusion)
if (server.getPreferredDownsamples().length == 1 || !server.containsSubImages()) {
ImporterOptions options = new ImporterOptions();
int series = server.getSeries();
options.setId(server.getFile().getAbsolutePath());
options.setOpenAllSeries(false);
options.setSeriesOn(series, true);
options.setCrop(true);
options.setCropRegion(server.getSeries(), new Region(request.getX(), request.getY(), request.getWidth(), request.getHeight()));
try {
ImagePlus[] imps = BF.openImagePlus(options);
assert imps.length == 1;
imp = imps[0];
} catch (Exception e) {
logger.warn("Unable to open with ImageJ: " + server, e);
}
} else {
logger.warn("Multiple multi-resolution series in file - skipping ImageJ check");
}
} catch (Exception e) {
e.printStackTrace();
}
// Check if we got a server at all
assertNotNull(server);
// Check if we got an image
assertNotNull(img);
// Get the thumbnail
assertNotNull(imgThumbnail);
// Check channel numbers
assertEquals(img.getRaster().getNumBands(), server.nChannels());
assertEquals(imgThumbnail.getRaster().getNumBands(), server.nChannels());
// Check pixel sizes
if (imp != null) {
PixelCalibration cal = server.getPixelCalibration();
if ("micron".equals(imp.getCalibration().getXUnit()))
assertEquals(imp.getCalibration().pixelWidth, cal.getPixelWidthMicrons(), 0.00001);
else
assertTrue(Double.isNaN(cal.getPixelWidthMicrons()));
if ("micron".equals(imp.getCalibration().getXUnit()))
assertEquals(imp.getCalibration().pixelHeight, cal.getPixelHeightMicrons(), 0.00001);
else
assertTrue(Double.isNaN(cal.getPixelHeightMicrons()));
// Check z-slices, if appropriate
if (server.nZSlices() > 1) {
if ("micron".equals(imp.getCalibration().getZUnit()))
assertEquals(imp.getCalibration().pixelDepth, cal.getZSpacingMicrons(), 0.00001);
else
assertTrue(Double.isNaN(cal.getZSpacingMicrons()));
}
// Check dimensions by comparison with ImageJ
assertEquals(img.getWidth(), imp.getWidth());
assertEquals(img.getHeight(), imp.getHeight());
assertEquals(server.nChannels(), imp.getNChannels());
assertEquals(server.nTimepoints(), imp.getNFrames());
assertEquals(server.nZSlices(), imp.getNSlices());
// Check actual pixel values
float[] samples = null;
float[] samplesIJ = null;
for (int c = 0; c < server.nChannels(); c++) {
samples = img.getRaster().getSamples(0, 0, img.getWidth(), img.getHeight(), c, samples);
imp.setPosition(c + 1, z + 1, t + 1);
samplesIJ = (float[]) imp.getProcessor().convertToFloatProcessor().getPixels();
// I am having some trouble comparing the full array with Java 10... trouble appears on IJ side..?
assertEquals(samples[0], samplesIJ[0], (float) 0.00001);
// assertArrayEquals(samples, samplesIJ, (float)0.00001);
}
}
printSummary(server);
}
}
Aggregations