回到首頁

ImageJ 自動化與巨集程式設計

巨集語言介紹

ImageJ使用一種簡單的內建腳本語言,稱為 ImageJ Macro Language

巨集錄製

ImageJ提供了一個方便的巨集錄製器,可以將手動操作轉換為巨集程式碼。

在ImageJ中錄製巨集:

基本語法

ImageJ Macro Language 的語法類似於C語言或其他腳本語言,但更簡化。 - 變數無需顯式宣告類型,直接賦值即可。 - 常見的運算子(+、-、*、/、=、>、<、==、!= 等)皆可使用。 - 條件判斷使用 ifif...else 結構。 - 迴圈結構包括 forwhile

範例:基本操作

// ==== 1. 數值類型與變數 ====
var number = 123;
var decimal = 3.14;
var text = "Hello ImageJ";
var array = newArray(1, 2, 3, 4, 5);

print("Number: " + number);
print("Decimal: " + decimal);
print("Text: " + text);

// 列印陣列
print("Array elements:");
for (i = 0; i < array.length; i++) {
    print(array[i]);
}


// ==== 2. 算術運算 ====
var a = 10;
var b = 3;

sum = a + b;
difference = a - b;
product = a * b;
quotient = a / b;

x = 5;
y = 7;
x += 1; // x = 6
y *= 2; // y = 14

print("Sum: " + sum);
print("Difference: " + difference);
print("Product: " + product);
print("Quotient: " + quotient);
print("x after +=1: " + x);
print("y after *=2: " + y);

// ==== 3. 邏輯運算 ====
var value = 75;
var threshold = 50;

if (value > threshold) {
    print("Above threshold");
}

var x_val = 10;
var y_val = 20;

if (x_val > 0 && y_val < 100) {
    print("Within range");
}

if (x_val < 0 || y_val > 100) {
    print("Out of range");
} else {
    print("Safe range");
}

函數與程序

範例


// 建立測試影像
newImage("Test", "8-bit black", 256, 256, 1);
print("Image created: " + getTitle());

// 獲取影像尺寸
width = getWidth();
height = getHeight();
print("Width: " + width + ", Height: " + height);

// 設定與讀取像素值
x = 100;
y = 100;
setPixel(x, y, 255); // 設定像素為白色
value = getPixel(x, y); // 讀取像素值
print("Pixel value at (" + x + "," + y + "): " + value);

// ==== 2. 用戶交互 ====

// 對話框輸入數字
Dialog.create("Input Example");
Dialog.addNumber("Value:", 0);
Dialog.show();
userValue = Dialog.getNumber();
print("User entered value: " + userValue);

// 文件選擇
filePath = File.openDialog("選擇檔案");
print("你選擇的檔案: " + filePath);

範例:使用者動作批次處理每一個slice


// ================================
// ImageJ Macro 範例:生成 Stack 並分析每個 slice
// ================================

macro "Generate Stack and Analyze" {

    // ==== 1. 生成 Stack ====
    width = 256;
    height = 256;
    n = 5; // Stack 幀數

    newImage("StackExample", "8-bit black", width, height, n);

    // 填充每一幀測試數據 (隨機亮點)
    for (i = 1; i <= n; i++) {
        setSlice(i);
        for (j = 0; j < 100; j++) { // 100 個隨機亮點
            x = floor(random() * width);
            y = floor(random() * height);
            setPixel(x, y, 255);
        }
    }

    print("Stack created with " + nSlices + " slices.");

    // ==== 2. 設置測量參數 ====
    run("Set Measurements...", "integrated display redirect=None decimal=3");

    // ==== 3. 對每一 slice 分析 ====
    waitForUser("圈選區域");        
    setTool(0);

    for (i = 1; i <= n; i++) {
        setSlice(i);                

        run("Measure");
    }

    print("Stack analysis completed.");
}

使用者互動

巨集可以與使用者進行互動,例如顯示訊息、請求使用者輸入參數。 這使得巨集更加靈活,可以適應不同的影像和需求。

範例:使用者互動

// 範例:彈出對話框讓使用者輸入粒子分析的最小尺寸
Dialog.create("粒子分析參數");
Dialog.addNumber("最小粒子尺寸 (pixels):", 100);
Dialog.show();
minSize = Dialog.getNumber();

if (minSize > 0) {
    run("Analyze Particles...", "size=" + minSize + "-Infinity display");
} else {
    print("最小尺寸無效,跳過分析。");
}

範例:文件批次處理

// ===== 主流程 Macro =====
macro "產生粒子範例並測量" {

    // ==== 1. 生成範例影像 ====

    imageN = 5; // 生成 5 張範例影像
    width = 512;
    height = 512;

    imgDir = getDirectory("選擇存檔資料夾");        
    generateSampleImages(imgDir, imageN, width, height);

    // ==== 2. 批次處理生成的範例影像 ====

    files = getFileList(imgDir);

    for (i = 0; i < files.length; i++) {
        if (endsWith(files[i], ".tif")) {
            processFile(imgDir + files[i]);
        }
    }
    // 將 summary 表格輸出到 CSV
    outputDir = getDirectory("選擇選擇要輸出的資料夾");        
    resultsFile = outputDir + "測量結果.csv";    
    saveAs("Results", resultsFile);
}

// ===== 生成範例影像 =====
function generateSampleImages(imgDir, imageN, width, height) {
    for (i = 1; i <= imageN; i++) {
        newImage("Sample_" + i, "8-bit black", width, height, 1);

        // 生成隨機亮點
        for (j = 0; j < 50; j++) { // 50 個亮點
            x = floor(random() * width);
            y = floor(random() * height);
            setPixel(x, y, 255);
        }

        saveAs("Tiff", imgDir + "Sample_" + i + ".tif");
        close();
    }
}

// ===== 測量 =====
function processFile(inputPath) {
    open(inputPath);


    // 測量粒子
    run("Set Measurements...", "area mean min max centroid redirect=None decimal=2");
    run("Analyze Particles...", "size=1-Infinity show=Nothing summarize");
    close();

}