Created
May 11, 2021 17:54
-
-
Save petebankhead/836ad532ea61b2fe1d489682db77f817 to your computer and use it in GitHub Desktop.
Find the 'brightest' circle in a fluorescence image in QuPath v0.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Find the 'brightest' circle in a fluorescence image in QuPath v0.2. | |
* | |
* This could be used for creating ROIs in a TMA image where each core is a separate image. | |
* | |
* @author Pete Bankhead | |
*/ | |
import ij.plugin.filter.RankFilters | |
import qupath.imagej.tools.IJTools | |
import qupath.lib.objects.PathObjects | |
import qupath.lib.regions.RegionRequest | |
import qupath.lib.roi.ROIs | |
import static qupath.lib.gui.scripting.QPEx.* | |
// Define the radius, in calibrated units (e.g. µm) | |
double radius = 1000 | |
// Define the channel to use (1-based index) | |
int channel = 1 | |
// Get the current image | |
def server = getCurrentServer() | |
int filterRadius = 10 // How large a filter we want to use in the downsampled image | |
double radiusPixels = radius / server.getPixelCalibration().getAveragedPixelSize() | |
double downsample = Math.max(1.0, radiusPixels / filterRadius) | |
def request = RegionRequest.createInstance(server, downsample) | |
def pathImage = IJTools.convertToImagePlus(server, request) | |
def imp = pathImage.getImage() | |
// Threshold each channel and add results | |
def fp = imp.getStack().getProcessor(channel).convertToFloatProcessor() | |
new RankFilters().rank(fp, filterRadius, RankFilters.MEAN) | |
// Find maximum location, avoiding the image boundary | |
int maxX = -1 | |
int maxY = -1 | |
float maxVal = Float.NEGATIVE_INFINITY | |
for (int y = filterRadius; y < fp.getHeight()-filterRadius; y++) { | |
for (int x = filterRadius; x < fp.getWidth()-filterRadius; x++) { | |
float val = fp.getf(x, y) | |
if (val > maxVal) { | |
maxVal = val | |
maxX = x | |
maxY = y | |
} | |
} | |
} | |
// Create an ellipse ROI | |
double x = maxX * request.getDownsample() + request.getMinX() - radiusPixels | |
double y = maxY * request.getDownsample() + request.getMinY() - radiusPixels | |
def roi = ROIs.createEllipseROI(x, y, radiusPixels * 2, radiusPixels * 2, request.getPlane()) | |
// Create an annotation | |
def annotation = PathObjects.createAnnotationObject(roi) | |
addObject(annotation) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment