首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【QuPath】你还在手动导出分析结果吗?

【QuPath】你还在手动导出分析结果吗?

作者头像
生信菜鸟团
发布2025-06-12 11:31:19
发布2025-06-12 11:31:19
5850
举报
文章被收录于专栏:生信菜鸟团生信菜鸟团

上回书➡ 【QuPath】Multiplexed analysis之多重免疫荧光分析教程说到建立多通道分类器并识别细胞,那么结果该如何一次性导出呢?

这就不得不提到qupath的灵活性了~

我们可以在script editor输入自己的脚本,实现很多功能——

图片
图片

一般情况下,我们对一张图像进行注释分析以后,对应的数据会存储在:

图片
图片

既然如此,我们当然也可以通过脚本的方式实现批量输出啦~

🧠 「Groovy 脚本是 QuPath 实现自动化分析的核心工具。」

  • Groovy 是一种运行在 Java 虚拟机上的脚本语言,语法简洁,兼容 Java。
  • 在 QuPath 中,Groovy 脚本用来操控图像、细胞对象、通道、测量值、批量处理等。
  • 通过编写脚本,你可以批量完成图像加载、细胞检测、筛选阳性、统计表达、导出 CSV 等操作,省去手动点选的麻烦。

下面的脚本可以实现对项目内每一张图像的结果进行批量导出,只需要更改自己的目标文件夹即可~

代码语言:javascript
复制
// 配置输出目录(您的路径)

def outputDir = "您的路径"

def outputFolder = new File(outputDir)

outputFolder.mkdirs()



// 检查项目

def project = getProject()

if (!project) {

    printError("没有打开的项目!")

return

}



// 获取图像列表

def images = project.getImageList()

if (images.isEmpty()) {

    printError("项目中无图像!")

return

}



printHeader("开始导出 ${images.size()} 张图像 → ${outputDir}")



// 核心导出函数

images.eachWithIndex { entry, idx ->

try {

def imageName = entry.getImageName()

        printProgress(idx+, images.size(), imageName)



// 读取图像数据(QuPath 0.5.1方式)

def imageData = entry.readImageData()

def hierarchy = imageData.getHierarchy()



// 获取检测对象(兼容细胞/注释对象)

def objects = hierarchy.getObjects(null, qupath.lib.objects.PathDetectionObject)

if (objects.isEmpty()) {

            println "  ⚠️ 无检测对象,跳过"

return

        }



// 生成CSV文件

def csvFile = new File(outputDir, "${imageName}_measurements.csv")

        exportMeasurementsToCSV(objects, csvFile)



    } catch (Exception e) {

        println "  ❌ 处理失败: ${e.message}"

        e.printStackTrace()

    }

}



// 导出完成提示

printSuccess("导出完成!共处理 ${images.size()} 张图像")

showNotification("数据导出完成", "结果已保存至:\n${outputDir}")



// ========== 工具函数 ==========

void exportMeasurementsToCSV(objects, csvFile) {

// 获取所有测量指标(去重+排序)

def measurements = objects.collectMany { it.getMeasurementList().getMeasurementNames() }

                             .unique().sort()



    csvFile.withWriter { writer ->

// 写入BOM头(解决Excel中文乱码)

        writer.write('\uFEFF')

// 表头

        writer.write("ObjectID,Class," + measurements.join(",") + "\n")

// 数据行

        objects.eachWithIndex { obj, i ->

def ml = obj.getMeasurementList()

            writer.write("${i+1},${obj.getPathClass()?.toString() ?: 'None'},")

            writer.write(measurements.collect { ml.getMeasurementValue(it) ?: "" }.join(","))

            writer.write("\n")

        }

    }

    println "  ✅ 已导出 → ${csvFile.name} (${objects.size()}个对象)"

}



// 进度显示

void printProgress(current, total, name) {

    printf("[%2d/%2d] %-40s ", current, total, name.length() >  ? name[0..37] + "..." : name)

}



// 信息格式化

void printHeader(msg) { println("="* + "\n" + msg + "\n" + "="*) }

void printError(msg) { System.err.println("❌ ERROR: " + msg) }

void printSuccess(msg) { println("\n" + "✓ " + msg + " " + "✓") }



// 弹窗通知

void showNotification(title, message) {

    javafx.application.Platform.runLater {

new javafx.scene.control.Alert(

            javafx.scene.control.Alert.AlertType.INFORMATION,

            message

        ).with {

            it.title = title

            it.headerText = null

            it.showAndWait()

        }

    }

}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信菜鸟团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档