在进行显微图像分析时,经常需要从大量图像中批量提取指定的 ROI 区域。如果手动逐张打开图像、选择 ROI、裁剪并保存,不仅效率很低,而且容易出现操作误差。
本文提供一个基于ImageJ / Fiji Macro的批处理脚本,可以实现以下功能:
- 批量读取指定文件夹中的图像;
- 加载提前保存好的 ROI 文件;
- 对每一张图像提取相同 ROI 区域;
- 将提取后的 ROI 图像自动保存到指定输出文件夹;
- 支持
.tif、.tiff、.png、.jpg、.jpeg等常见图像格式。
该方法适用于需要对同一批图像进行相同区域裁剪、细胞局部区域提取、显微图像 ROI 分析等场景。
一、使用前准备
在运行代码前,需要先准备以下内容:
- 存放原始图像的文件夹;
- 已经选定并保存好的 ROI 文件;
- 用于保存提取结果的输出文件夹。
ROI 文件一般通过 ImageJ 的 ROI Manager 保存。
具体操作如下:
打开图像后,使用矩形、椭圆、多边形或自由选择工具圈定 ROI 区域,然后点击:
Analyze > Tools > ROI Manager在 ROI Manager 中点击:
Add如果有多个 ROI,可以依次添加。添加完成后,点击:
More > Save...将 ROI 保存为.zip文件,例如:
ROIs.zip二、完整 ImageJ / Fiji Macro 代码
将下面代码复制到 ImageJ / Fiji 的 Macro 编辑器中即可运行。
// ============================================================ // Batch Extract ROI Regions in ImageJ / Fiji // 功能:批量提取文件夹中所有图像的 ROI 区域,并保存为 TIFF 文件 // 作者:百变小水果 // 适用软件:ImageJ / Fiji // ============================================================ // ------------------------------------------------------------ // 1. 选择输入图像文件夹 // ------------------------------------------------------------ inputDir = getDirectory("Choose input image folder"); // ------------------------------------------------------------ // 2. 选择已经保存好的 ROI zip 文件 // ------------------------------------------------------------ roiPath = File.openDialog("Choose ROI zip file"); // ------------------------------------------------------------ // 3. 选择输出文件夹 // ------------------------------------------------------------ outputDir = getDirectory("Choose output folder"); // ------------------------------------------------------------ // 4. 设置支持的图像格式 // ------------------------------------------------------------ extensions = newArray(".tif", ".tiff", ".png", ".jpg", ".jpeg"); // ------------------------------------------------------------ // 5. 获取输入文件夹中的所有文件 // ------------------------------------------------------------ fileList = getFileList(inputDir); // ------------------------------------------------------------ // 6. 打开 ROI Manager 并加载 ROI 文件 // ------------------------------------------------------------ run("ROI Manager..."); roiManager("Reset"); roiManager("Open", roiPath); // 获取 ROI 数量 roiCount = roiManager("Count"); if (roiCount == 0) { exit("No ROI found. Please check your ROI zip file."); } // ------------------------------------------------------------ // 7. 开启批处理模式,提高运行速度 // ------------------------------------------------------------ setBatchMode(true); // ------------------------------------------------------------ // 8. 遍历输入文件夹中的所有图像 // ------------------------------------------------------------ for (i = 0; i < fileList.length; i++) { fileName = fileList[i]; // 跳过子文件夹 if (File.isDirectory(inputDir + fileName)) { continue; } // 判断是否为支持的图像格式 lowerName = toLowerCase(fileName); isImage = false; for (e = 0; e < extensions.length; e++) { if (endsWith(lowerName, extensions[e])) { isImage = true; } } if (!isImage) { continue; } // -------------------------------------------------------- // 9. 打开当前图像 // -------------------------------------------------------- open(inputDir + fileName); originalTitle = getTitle(); // 去掉文件扩展名,作为输出文件名前缀 dotIndex = lastIndexOf(fileName, "."); if (dotIndex >= 0) { baseName = substring(fileName, 0, dotIndex); } else { baseName = fileName; } // -------------------------------------------------------- // 10. 对当前图像中的每一个 ROI 进行提取 // -------------------------------------------------------- for (r = 0; r < roiCount; r++) { selectWindow(originalTitle); // 选择第 r 个 ROI roiManager("Select", r); // 获取 ROI 名称 roiName = Roi.getName(); if (roiName == "") { roiName = "ROI_" + (r + 1); } // 清理 ROI 名称中的非法文件名字符 roiName = replace(roiName, "/", "_"); roiName = replace(roiName, "\\", "_"); roiName = replace(roiName, ":", "_"); roiName = replace(roiName, "*", "_"); roiName = replace(roiName, "?", "_"); roiName = replace(roiName, "\"", "_"); roiName = replace(roiName, "<", "_"); roiName = replace(roiName, ">", "_"); roiName = replace(roiName, "|", "_"); // ---------------------------------------------------- // 11. 复制 ROI 区域 // ---------------------------------------------------- // 对于单张图像,会复制当前 ROI 区域; // 对于 stack 或 hyperstack 图像,会尽量保留原始堆栈结构。 run("Duplicate...", "title=" + baseName + "_" + roiName + " duplicate"); // ---------------------------------------------------- // 12. 保存提取后的 ROI 图像 // ---------------------------------------------------- saveAs("Tiff", outputDir + baseName + "_" + roiName + ".tif"); // 关闭当前 ROI 图像 close(); } // -------------------------------------------------------- // 13. 关闭原始图像 // -------------------------------------------------------- selectWindow(originalTitle); close(); } // ------------------------------------------------------------ // 14. 关闭批处理模式 // ------------------------------------------------------------ setBatchMode(false); print("Batch ROI extraction finished.");三、运行方法
打开 Fiji 或 ImageJ 后,按照以下步骤运行:
- 选择:
Plugins > New > Macro- 将上面的代码复制进去;
- 点击:
Run- 程序会依次要求选择:
原始图像文件夹 ROI zip 文件 输出结果文件夹- 选择完成后,程序会自动批量处理图像。
四、输出结果
假设输入文件夹中有如下图像:
image1.tif image2.tif image3.tifROI 文件中包含两个 ROI:
ROI_1 ROI_2那么输出文件夹中会生成:
image1_ROI_1.tif image1_ROI_2.tif image2_ROI_1.tif image2_ROI_2.tif image3_ROI_1.tif image3_ROI_2.tif也就是说,每一张图像都会按照 ROI 文件中的区域进行裁剪,并分别保存为新的 TIFF 文件。
本文提供了一个基于 ImageJ / Fiji Macro 的批量 ROI 提取脚本。通过该脚本,可以自动完成图像读取、ROI 加载、区域裁剪和结果保存等步骤,适合用于显微图像分析、细胞图像定量分析以及批量图像预处理流程。
相比手动逐张裁剪,该方法可以显著提高处理效率,并减少人为操作误差。