使用 Imagej 進行圖像處理時,常常會遇到存在大量圖片,但處理方法相同的情況。如果耗費大量時間用鼠標進行相同的操作,難免會感到無聊,甚至出錯。通過編寫 ImageJ 的腳本 Script,我們可以實現 ImageJ 的自動化,從而節省時間,“一勞永逸”。
本方法有 3 個步驟:
- 通過 Recorder 記錄操作的 Command
- 用自己喜歡的編程語言編寫腳本(本例采用 Python 示范)
- 運行腳本
Command Recorder
使用 Command Recorder 能夠為后續的腳本編寫提供便捷。
Command Recorder 與 Macro 宏
Command Recorder 是在我們操作 ImageJ 時,同時記錄下內部指令的軟件。據 ImageJ 官方的介紹
Macro 宏 是一個簡單的程序,可以自動執行一系列 ImageJ 指令。創建宏的最簡單方法是使用 Command Recorder 指令記錄器 記錄指令系列,並保存為文本文件,這個文本文件即為宏。通過選擇菜單命令、按鍵或單擊 ImageJ 工具欄中的圖標來執行保存的宏。
為什么不直接使用 Macro 編寫腳本?
官方對 ImageJ 宏的特性描述是
ImageJ 宏語言不如其他腳本語言強大,但設計為易於學習和使用。
當你需要更復雜的功能,或與 ImageJ 之外的程序進行交互時,宏就顯得不是那么方便了。在此,因為我有一定的 Python 基礎,所以我果斷地選擇了 Python。ImageJ 官方對 Python 的描述是:
Python是科學家的熱門選擇。您可以在 ImageJ 內部使用其 script editor(/scripting/script-editor)編寫 Jython scripts(/scripting/jython)(一種基於 Java 的 Python 2 語言),或者使用 PyImageJ(/scripting/pyimagej) 從 Python 腳本調用 ImageJ 函數。
ImageJ 腳本還支持采用其他語言編寫,如 Groovy, JavaScript, Ruby (JRuby), Lisp (Clojure), R (Renjin), Java, MATLAB, BeanShell, Java.
編寫腳本
采用 Python 編寫 ImageJ 腳本有 2 種方式,官方對其作了比較 Python (imagej.net):
- 在 ImageJ 內部編寫、運行,類似於采用其他語言腳本的方法。
- 優點:能夠利用 SciJava 腳本參數,並在支持 SciJava 的多個工具中運行。
- 缺點:將無法使用許多需要本地代碼(如 numpy 或 scipy)的 Python 模塊。
- 缺點:目前僅支持 Python2 - 采用 pyimagej · PyPI 將 ImageJ 嵌入到 Python 代碼中。
- 優點:可以將 ImageJ 與其他圖像分析庫(如 scikit-image,ITK,OpenCV 等)在單個Python 程序中結合使用。
- 缺點:在 Python 中封裝 ImageJ 存在一些限制,有一些 ImageJ 的功能無法很好地發揮作用。
本文采用 方案 1 ,因為作者在使用 方案 2 的時候,出現了一些尚未解決的問題(尷尬)。
從哪里開始?
新建一個腳本文件十分簡單,僅需 File - New - Script
,若要使用 Python,則在腳本編輯器的菜單中選擇 File - New - Script
。
幾乎所有的 ImageJ 中的 Python 腳本的頭部都包含一行:
from ij import IJ
從Package 包 "ij" 導入Namespace 命名空間 "IJ" 。 命名空間 是一組函數。包是一組命名空間。
關於采用 Python 編寫 Script 的更多指南,可以從 Fiji Programming Tutorial (cam.ac.uk) 和 Welcome to Python.org 獲取。本文重點在腳本中插件的使用。
如何在 Python 腳本中使用插件?
有 2 種方法在 Python 腳本中使用插件
ij.plugin.<模塊名>
- 通過
IJ.run()
直接執行 Macro Command 宏指令
通過 ij.plugin
引入模塊
在 Command Finder 中,能夠查找到,為實現一個功能,應該引用哪個模塊。具體操作如下:
- 打開 Command Finder:
Plugins - Utilities - Find commands...
- 輸入與命令相關的關鍵詞,便會找到一系列指令
- 在指令的 "Class" 欄中,列出了實現它的插件類,注意尋找
ij.plugin
打頭的
如此一來我們便能實現插件在 Python 腳本中的使用。但還有一點,參數該填什么?
有 2 個方法尋找參數:
- Fiji java documentation ,也能夠通過
Tools - Open help for class (with frames)
打開 - 插件存儲在網絡上的 source code,在搜索引擎中進行搜索
綜上,這種方法較為困難。我們需要一種更為直觀而簡便的方法來編寫程序。
通過 IJ.run()
執行宏指令
這種方法較為簡單快速,采用 Command Recorder,在用鼠標操作 ImageJ 時,便會記錄下宏指令。將宏指令直接粘貼到 IJ.run()
中,即可執行。本例即采用此法。
舉例
本例需要批量處理一系列 .ims 格式的熒光顯微鏡圖片,將其 3 個通道分出,再兩兩不同通道 merge,隨后人工觀察一些蛋白的 foci,及共定位現象。加黑部分采用 ImageJ 完成。
# 敬告,路徑中不可有空格,且輸出文件夾不需要預先建立
# 敬告,請使用雙反斜杠
from ij import IJ
import os
folder = "D:\\samples" # 打開文件夾
# 限定各通道顯示閾值
c_MinMax = {"0": [100, 500],
"1": [100, 500],
"2": [130, 180]}
# 需要合並哪些通道及對應的顏色
c_Merge = {"01": "01", "02": "02", "12": "12"}
os.mkdir(os.path.join(folder, 'out')) # 新建輸出文件夾
# 對每張圖片進行操作
for i, filename in enumerate(os.listdir(folder)):
if filename[-4:] == '.ims': # 判斷是否為 ims 圖片文件
img_path = os.path.join(folder, filename) # 圖片路徑
# 采用 Bio-Formats 讀入圖片
img_open_attr = "open=" + img_path + " autoscale \
color_mode=Default rois_import=[ROI manager] \
split_channels view=Hyperstack stack_order=XYCZT"
IJ.run("Bio-Formats Importer", img_open_attr)
save_path = os.path.join(folder, 'out', filename) # 新生成圖片保存路徑
# 保存拆分開各通道的圖片
for c in ["0", "1", "2"]:
IJ.selectWindow(filename + " - C=" + c) # 焦點選擇該通道讀入圖片
IJ.run("Brightness/Contrast...") # 打開調整明暗、對比的窗口
IJ.setMinAndMax(c_MinMax[c][0], c_MinMax[c][1]) # 調整明暗對比
IJ.saveAs("PNG", save_path+" - C="+c+".png") # 保存圖片
# 保存任意 2 個通道合並的圖片
for pic_n in c_Merge.keys():
pic1, pic2 = pic_n[0], pic_n[1]
IJ.run("Merge Channels...", "c1=[%(filename)s - C=%(pic1)s.png] c3=[%(filename)s - C=%(pic2)s.png] create keep"
% {"filename": filename, "pic1": pic1, "pic2": pic2})
IJ.saveAs("PNG", save_path + "Composite_%s.png" % c_Merge[pic_n])
IJ.run("Close")
# 保存 3 個通道全部合並的圖片
IJ.run("Merge Channels...", "c1=[%s - C=2.png] c2=[%s - C=1.png] c3=[%s - C=0.png] create keep"
% (filename, filename, filename))
IJ.saveAs("PNG", save_path + "Composite_B_G_R.png")
# 關閉全部窗口
IJ.run("Close All")