You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QuPath高效内存脚本开发:获取肿瘤内外边缘区域

优化后的QuPath脚本:提取6类组织区域

核心思路

基于QuPath原生的GeometryTools和RegionTools高效处理形态学运算,先合并同类型注释减少运算量,复用中间结果避免重复计算,全程以几何形状为核心操作,大幅降低内存占用与运行时间。

完整可运行脚本

import qupath.lib.geom.GeometryTools
import qupath.lib.objects.PathAnnotationObject
import qupath.lib.objects.classes.PathClassFactory

// 配置关键参数
def tumorClassName = "Tumor"
def tissueClassName = "Tissue"
def innerDistance = 60.0  // μm
def outerDistance = 120.0 // μm

// 获取并预处理注释:合并同类型所有注释为单个几何形状
def tumorAnnos = getAnnotationObjects().findAll { it.getPathClass()?.getName() == tumorClassName }
def tissueAnnos = getAnnotationObjects().findAll { it.getPathClass()?.getName() == tissueClassName }

if (tumorAnnos.isEmpty() || tissueAnnos.isEmpty()) {
    print("错误:缺少肿瘤或整体组织注释!")
    return
}

def tumorGeom = GeometryTools.union(tumorAnnos.collect { it.getROI().getGeometry() })
def tissueGeom = GeometryTools.union(tissueAnnos.collect { it.getROI().getGeometry() })

// 计算各类目标区域
def regionMap = [:]

// 1. 非肿瘤非边缘组织 = 整体组织 - 肿瘤向外扩展120μm的区域
def tumorExpand120 = GeometryTools.buffer(tumorGeom, outerDistance, true)
regionMap["非肿瘤非边缘组织"] = tissueGeom.difference(tumorExpand120)

// 2. 肿瘤周边60-120μm区域 = 肿瘤120μm缓冲区 - 肿瘤60μm缓冲区,再与整体组织取交集
def tumorExpand60 = GeometryTools.buffer(tumorGeom, innerDistance, true)
regionMap["肿瘤周边60-120μm区域"] = tumorExpand120.difference(tumorExpand60).intersection(tissueGeom)

// 3. 肿瘤周边0-60μm区域 = 肿瘤60μm缓冲区 - 肿瘤区域,再与整体组织取交集
regionMap["肿瘤周边0-60μm区域"] = tumorExpand60.difference(tumorGeom).intersection(tissueGeom)

// 4. 肿瘤内部0-60μm区域 = 肿瘤区域 - 肿瘤向内收缩60μm的区域
def tumorShrink60 = GeometryTools.buffer(tumorGeom, -innerDistance, true)
regionMap["肿瘤内部0-60μm区域"] = tumorGeom.difference(tumorShrink60)

// 5. 肿瘤内部60-120μm区域 = 肿瘤向内收缩60μm的区域 - 肿瘤向内收缩120μm的区域
def tumorShrink120 = GeometryTools.buffer(tumorGeom, -outerDistance, true)
regionMap["肿瘤内部60-120μm区域"] = tumorShrink60.difference(tumorShrink120)

// 6. 剩余肿瘤组织 = 肿瘤向内收缩120μm的区域
regionMap["剩余肿瘤组织"] = tumorShrink120

// 将计算结果转为注释添加到图像
regionMap.each { name, geom ->
    if (!geom.isEmpty()) {
        def roi = GeometryTools.geometryToROI(geom, getCurrentImageData().getServer().getPixelCalibration())
        def anno = new PathAnnotationObject(roi)
        anno.setPathClass(PathClassFactory.getPathClass(name))
        addObject(anno)
    } else {
        print("警告:区域「$name」为空,跳过创建注释")
    }
}

print("所有区域提取完成!")

效率优化细节

  • 合并注释预处理:将同类型的分散注释合并为单个几何形状,减少后续运算的循环次数
  • 复用中间结果:比如tumorExpand60同时用于计算周边0-60μm和内部0-60μm区域,避免重复执行缓冲运算
  • 原生几何运算:依赖QuPath底层的JTS几何库,比自定义像素级遍历效率高数十倍
  • 空值拦截:提前检查注释是否存在,跳过空区域的注释创建,避免无效操作

注意事项

  • 确保图像已正确设置像素校准(单位为μm),否则距离计算会出现偏差
  • 若肿瘤存在多个不连通区域,union方法会自动合并为单个几何形状,不影响区域计算逻辑
  • 若肿瘤尺寸过小导致某类区域为空(比如肿瘤直径小于120μm时,内部60-120μm区域不存在),脚本会打印警告并跳过该区域

内容的提问来源于stack exchange,提问作者fgootkind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:35:14