在xampp下搭建本地网站,怎么建立一个wordpress,企业网站更新什么内容,wordpress官方模版文献中详细介绍了处理HE scripts的详细过程#xff0c;计算HE染色的全切片中的肿瘤基质百分比。
步骤#xff1a;
1.将相关幻灯片添加到QuPath项目中。
2.对于项目中的每张幻灯片#xff0c;围绕一个有代表性的肿瘤区域绘制一个注释。
3.运行“Estimate _ bac…
文献中详细介绍了处理HE scripts的详细过程计算HE染色的全切片中的肿瘤基质百分比。
步骤
1.将相关幻灯片添加到QuPath项目中。
2.对于项目中的每张幻灯片围绕一个有代表性的肿瘤区域绘制一个注释。
3.运行“Estimate _ background _ values . groovy”来自动确定适当的“白色”值以改进光学计算 密度。这是可选的但可能对较暗的扫描有帮助它预先假定背景区域在图像中的某处是可用的。
4.运行“HE_superpixels_script.groovy”来计算注释区域内的超像素和特征。
5.使用“分类-创建检测分类器”以交互方式训练分类器以区分 形象。完成后将此分类器应用于所有图像。
6.运行 Export_HE_tumor_areas.groovy 来导出结果
1,Estimate_background_values.groovy
/**
* Script to estimate the background value in a brightfield whole slide image.
*
* This effectively looks for the circle of a specified radius with the highest
* mean intensity (summed across all 3 RGB channels), and takes the mean red,
* green and blue within this circle as the background values.
*
* The background values are then set in the ColorDeconvolutionStains object
* for the ImageData, so that they are used for any optical density calculations.
*
* This is implemented with the help of ImageJ (www.imagej.net).
*
* author Pete Bankhead
*/
import ij.plugin.filter.RankFilters
import ij.process.ColorProcessor
import qupath.imagej.images.servers.ImagePlusServerBuilder
import qupath.lib.common.ColorTools
import qupath.lib.regions.RegionRequest
import qupath.lib.scripting.QP
// Radius used for background search, in microns (will be used approximately)
double radiusMicrons 1000
// Calculate a suitable preferred pixel size
// Keep in mind that downsampling involves a form of smoothing, so we just choose
// a reasonable filter size and then adapt the image resolution accordingly
double radiusPixels 10
double requestedPixelSizeMicrons radiusMicrons / radiusPixels
// Get the ImageData ImageServer
def imageData QP.getCurrentImageData()
def server imageData.getServer()
// Check we have the right kind of data
if (!imageData.isBrightfield() || !server.isRGB()) {print(ERROR: Only brightfield RGB images can be processed with this script, sorry)return
}
// Extract pixel size
double pixelSize server.getAveragedPixelSizeMicrons()
// Choose a default if we need one (i.e. if the pixel size is missing from the image metadata)
if (Double.isNaN(pixelSize))pixelSize 0.5
// Figure out suitable downsampling value
double downsample Math.round(requestedPixelSizeMicrons / pixelSize)
// Get a downsampled version of the image as an ImagePlus (for ImageJ)
def request RegionRequest.createInstance(server.getPath(), downsample, 0, 0, server.getWidth(), server.getHeight())
def serverIJ ImagePlusServerBuilder.ensureImagePlusWholeSlideServer(server)
def pathImage serverIJ.readImagePlusRegion(request)
// Check we have an RGB image (we should at this point)
def imp pathImage.getImage(false)
def ip imp.getProcessor()
if (!(ip instanceof ColorProcessor)) {print(Sorry, the background can only be set for a ColorProcessor, but the current ImageProcessor is ip)return
}
// Apply filter
if (ip.getWidth() radiusPixels*2 || ip.getHeight() radiusPixels*2) {print(The image is too small for the requested radius!)return
}
new RankFilters().rank(ip, radiusPixels, RankFilters.MEAN)
// Find the location of the maximum across all 3 channels
double maxValue Double.NEGATIVE_INFINITY
double maxRed 0
double maxGreen 0
double maxBlue 0
for (int y radiusPixels; y ip.getHeight()-radiusPixels; y) {for (int x radiusPixels; x ip.getWidth()-radiusPixels; x) {int rgb ip.getPixel(x, y)int r ColorTools.red(rgb)int g ColorTools.green(rgb)int b ColorTools.blue(rgb)double sum r g bif (sum maxValue) {maxValue summaxRed rmaxGreen gmaxBlue b}}
}
// Print the result
print(Background RGB values: maxRed , maxGreen , maxBlue)
// Set the ImageData stains
def stains imageData.getColorDeconvolutionStains()
def stains2 stains.changeMaxValues(maxRed, maxGreen, maxBlue)
imageData.setColorDeconvolutionStains(stains2)2,HE_superpixels_script.groovy
/*
* Generate superpixels compute features for HE tumor stromal analysis using QuPath.
*
* author Pete Bankhead
*/
// Compute superpixels within annotated regions
selectAnnotations()
runPlugin(qupath.imagej.superpixels.SLICSuperpixelsPlugin, {sigmaMicrons: 5.0, spacingMicrons: 40.0, maxIterations: 10,
regularization: 0.25, adaptRegularization: false, useDeconvolved: false});
// Add Haralick texture features based on optical densities, and mean Hue for each superpixel
selectDetections();
runPlugin(qupath.lib.algorithms.IntensityFeaturesPlugin, {pixelSizeMicrons: 2.0, region: ROI, tileSizeMicrons: 25.0, colorOD:
true, colorStain1: false, colorStain2: false, colorStain3: false, colorRed: false, colorGreen: false, colorBlue: false,
colorHue: true, colorSaturation: false, colorBrightness: false, doMean: true, doStdDev: false, doMinMax: false, doMedian:
false, doHaralick: true, haralickDistance: 1, haralickBins: 32});
// Add smoothed measurements to each superpixel
selectAnnotations();
runPlugin(qupath.lib.plugins.objects.SmoothFeaturesPlugin, {fwhmMicrons: 50.0, smoothWithinClasses: false, useLegacyNames:
false});
3,Export_HE_tumor_areas.groovy
/**
* Script to compute areas for detection objects with different classifications.
*
* Primarily useful for converting classified superpixels into areas.
*
* author Pete Bankhead
*/
import qupath.lib.common.GeneralTools
import qupath.lib.gui.QuPathGUI
import qupath.lib.images.servers.ImageServer
import qupath.lib.objects.PathDetectionObject
import qupath.lib.objects.PathObject
import qupath.lib.objects.classes.PathClass
import qupath.lib.objects.classes.PathClassFactory
import qupath.lib.objects.hierarchy.PathObjectHierarchy
import qupath.lib.roi.interfaces.PathArea
import qupath.lib.roi.interfaces.ROI
import qupath.lib.scripting.QPEx
import qupath.lib.gui.ImageWriterTools
import qupath.lib.regions.RegionRequest
import java.awt.image.BufferedImage
//----------------------------------------------------------------------------
// If exportImages is true, overview images will be written to an export subdirectory
// of the current project, otherwise no images will be exported
boolean exportImages true
// Define which classes to analyze, in terms of determining areas etc.
def classesToAnalyze [Tumor, Stroma, Other]
// Format output 3 decimal places
int nDecimalPlaces 3
// If the patient ID is encoded in the filename, a closure defined here can parse it
// (By default, this simply strips off anything after the final dot - assumed to be the file extension)
def parseUniqueIDFromFilename { n -int dotInd n.lastIndexOf(.)if (dotInd 0)return nreturn n.substring(0, dotInd)
}
// The following closure handled the specific naming scheme used for the images in the paper
// Uncomment to apply this, rather than the default method above
//parseUniqueIDFromFilename {n -
// def uniqueID n.trim()
// if (uniqueID.charAt(3) -)
// uniqueID uniqueID.substring(0, 3) uniqueID.substring(4)
// return uniqueID.split([-. ])[0]
// }
//----------------------------------------------------------------------------
// Convert class name to PathClass objects
SetPathClass pathClasses new TreeSet()
for (String className : classesToAnalyze) {pathClasses.add(PathClassFactory.getPathClass(className))
}
// Get a formatter
// Note: to run this script in earlier versions of QuPath,
// change createFormatter to getFormatter
def formatter GeneralTools.createFormatter(nDecimalPlaces)
// Get access to the current ImageServer - required for pixel size information
ImageServer? server QPEx.getCurrentImageData().getServer()
double pxWidthMM server.getPixelWidthMicrons() / 1000
double pxHeightMM server.getPixelHeightMicrons() / 1000
// Get access to the current hierarchy
PathObjectHierarchy hierarchy QPEx.getCurrentHierarchy()
// Loop through detection objects (here, superpixels) and increment total area calculations for each class
MapPathClass, Double areaMap new TreeMap()
double areaTotalMM 0
for (PathObject tile : hierarchy.getObjects(null, PathDetectionObject.class)) {// Check the classificationPathClass pathClass tile.getPathClass()if (pathClass null)continue// Add current areaROI roi tile.getROI()if (roi instanceof PathArea) {double area ((PathArea)roi).getScaledArea(pxWidthMM , pxHeightMM)areaTotalMM areaif (areaMap.containsKey(pathClass))areaMap.put(pathClass, area areaMap.get(pathClass))elseareaMap.put(pathClass, area)}
}
// Loop through each classification prepare output
double areaSumMM 0
double areaTumor 0
double areaStroma 0
// Include image name ID
String delimiter \t
StringBuilder sbHeadings new StringBuilder(Image).append(delimiter).append(Unique ID)
String uniqueID parseUniqueIDFromFilename(server.getShortServerName())
StringBuilder sb new StringBuilder(server.getShortServerName()).append(delimiter).append(uniqueID)
// Compute areas per class
for (PathClass pathClass : pathClasses) {// Extract area from map - or zero, if it does not occur in the mapdouble area areaMap.containsKey(pathClass) ? areaMap.get(pathClass) : 0// Update total record tumor area, if requiredareaSumMM areaif (pathClass.getName().toLowerCase().contains(tumor) || pathClass.getName().toLowerCase().contains(tumour))areaTumor areaif (pathClass.getName().toLowerCase().contains(stroma))areaStroma area// Display area for classificationsbHeadings.append(delimiter).append(pathClass.getName()).append( Area mm^2)sb.append(delimiter).append(formatter.format(area))
}
// Append the total area
sbHeadings.append(delimiter).append(Total area mm^2)
sb.append(delimiter).append(formatter.format(areaTotalMM))
// Append the calculated stromal percentage
sbHeadings.append(delimiter).append(Stromal percentage)
sb.append(delimiter).append(formatter.format(areaStroma / (areaTumor areaStroma) * 100.0))
// Export images in a project sub-directory, if required
if (exportImages) {// Create the directory, if requireddef path QPEx.buildFilePath(QPEx.PROJECT_BASE_DIR, export)QPEx.mkdirs(path)// We need to get the display settings (colors, line thicknesses, opacity etc.) from the current viewerdef overlayOptions QuPathGUI.getInstance().getViewer().getOverlayOptions()def imageData QPEx.getCurrentImageData()def name uniqueID// Aim for an output resolution of approx 20 µm/pixeldouble requestedPixelSize 20double downsample requestedPixelSize / server.getAveragedPixelSizeMicrons()RegionRequest request RegionRequest.createInstance(imageData.getServerPath(), downsample, 0, 0, server.getWidth(), server.getHeight())// Write output image, with and without overlaydef dir new File(path)def fileImage new File(dir, name .jpg)BufferedImage img ImageWriterTools.writeImageRegion(imageData.getServer(), request, fileImage.getAbsolutePath())def fileImageWithOverlay new File(dir, name -overlay.jpg)ImageWriterTools.writeImageRegionWithOverlay(img, imageData, overlayOptions, request, fileImageWithOverlay.getAbsolutePath())
}
// Write header to output file if its empty, and print on screen
sbHeadings.append(\n)
sb.append(\n)
def fileOutput new File(QPEx.buildFilePath(QPEx.PROJECT_BASE_DIR, Results.txt))
if (fileOutput.length() 0) {print(sbHeadings.toString())fileOutput sbHeadings.toString()
}
// Write data to output file print on screen
fileOutput sb.toString()
print(sb.toString())
参考
1QuPath: Open source software for digital pathology image analysis - PMC (nih.gov)
2:【WSI/QuPath】如何使用QuPath导出切片patch/tile-CSDN博客