MINC/軟體開發/MINC2.0 使用者指南
MINC 是一個用於儲存和處理醫學影像的軟體系統,最初由麥吉爾腦成像中心的彼得·尼林於 1993 年開發。MINC 的名字是醫學成像網路通用資料格式 (Medical Imaging NetCDF) 的縮寫。MINC 的構想是允許研究人員使用一組通用的工具和檔案來處理各種模態的醫學影像。該檔案格式最初被定義為由 UCAR (大學大氣研究公司) 的 Unidata 專案中心建立的 NetCDF (網路通用資料格式) 檔案格式的專門形式。NetCDF 格式、庫和工具旨在儲存任意維度的通用資料集。選擇 NetCDF 是因為它實現了為 MINC 系統設想的許多功能。
與大多數其他醫學影像資料格式一樣,MINC 允許醫學影像資料採用各種資料型別或範圍,並定義一組標準支援資料來描述影像採集引數或患者詳細資訊。
然而,MINC 在幾個方面不同於大多數其他醫學影像格式
- MINC 本質上是N 維的。MINC 資料可以採用任意數量的空間、時間或其他維度進行結構化,並且這些維度可以按任意順序組織。實際上,NetCDF 將資料限制為最多 100 個維度,但這並沒有被證明是一個有意義的限制。
- MINC 是多模態的。MINC 已被用於儲存 CT、MRI、PET、EEG 和其他醫學影像資料。
- MINC 是可擴充套件的。MINC 檔案可以包含任意數量的支援屬性和資料。如果您的研究要求您跟蹤患者的血壓或精神病史,則可以將這些資訊新增到您的 MINC 檔案的標題中,而無需擔心
- MINC 是自描述的。MINC 中使用的大多數屬性和變數都具有描述性名稱和值,使用者可以輕鬆解釋。
- MINC 允許基於每個影像或每個切片的體素資料的縮放。
- MINC 定義了體素和世界座標系。MINC 檔案有效地儲存了一個線性變換,該變換定義了檔案中體素的邏輯佈局與某個參考物理座標系之間的關係。物理座標系可以是掃描器的本機座標,也可以是更通用的座標空間,例如 Talairach 系統。
與許多專業計算術語一樣,“MINC”一詞多年來以多種不同的方式使用。它可以指檔案格式本身,即 MINC 檔案中資料的物理和邏輯佈局的定義。它也被應用於程式設計環境,該環境存在於提供對 MINC 格式檔案的訪問。最後,該術語有時指快速發展的分析、修改或顯示 MINC 檔案的程式和指令碼集。
“核心”MINC 系統可以被認為包括以下內容
- 檔案格式本身
- “libminc”程式設計介面,允許程式設計師完全訪問格式。
- “volume_io”程式設計介面,它提供了一個簡化的但受限的程式設計介面來訪問 MINC 格式。
- 使用這些庫編寫的一組工具。
除了核心 MINC 工具之外,還存在大量額外的應用程式,它們對 MINC 檔案執行更復雜的操作。這些包括用於視覺化、影像增強或校正、自動組織分類和影像配準的程式。
MINC 2 的設計旨在解決在 MINC 1 中發現的幾個特定問題。
- 檔案大小限制。使用的 NetCDF 檔案格式使用 32 位指標來定址檔案中的物件。這有效地將檔案限制為最大 2 GB 的大小。隨著非常高解析度的大腦圖譜資料 (來自宏觀切片機或其他來源) 和大型 fMRI 資料集的出現,很明顯這種限制可能會成為一個嚴重問題。
- 資料型別限制。NetCDF 格式定義了一組小的固定資料型別 - 整數、浮點數和 ASCII 字串。NetCDF 不支援聚合資料 (陣列或結構) 或帶標籤 (列舉) 的資料作為基本資料型別。
- 儲存選項有限。NetCDF 檔案將資料儲存在一個連續的陣列中。這會阻止在 NetCDF 格式中新增塊可定址資料或內部資料壓縮。
由於大多數這些問題都存在於 MINC 1 檔案格式中,因此很明顯 MINC 2 的設計將需要對檔案格式進行重大修改。開發 MINC 2 的團隊選擇用 HDF5 庫替換 NetCDF,作為 MINC 2 格式的基礎。HDF5 提供了許多 NetCDF 中不可用的高階功能。
- 超立方體 - N 維資料塊。如果所有維度都相等,則稱為“超立方體”。
- 不透明資料型別 - 面向物件的概念,用於引用其實現細節對程式設計師明確隱藏的資料型別。
- 向量維度 - 維度 (必須始終是最快變化的維度),它指定影像中特定點的數值,例如 RGB 影像。在 MINC2.0 中,向量被認為是記錄型別,可以透過為卷設定 flatten_flag (卷將有一個額外的維度,該維度將被設定為記錄) 來建立。
- 卷 - MINC 檔案。卷和檔案可以互換使用,因為使用卷用於超過 3 個維度並不常見,而 MINC 2 是 N 維的。
- 體素 - 體積元素,類似於“畫素”表示“影像元素”。多維影像中的單個數據點。
- 體素和世界座標系 - MINC 2 定義了“體素”和“世界”空間座標系。
對於每個維度,世界座標轉換由以下屬性指定:step、start 和 direction_cosines,因為 MINC 檔案允許具有非正交軸,維度與命名軸不完全對齊。例如,xspace 世界座標使用 x = (v*step + start) * direction_cosines 計算,其中 x 是 x 世界座標,v 是體素計數 (從零開始)。假設 xspace 維度與世界 x 軸一致,即 direction_cosine = (1,0,0),則 step 屬性的大小指定體素之間的距離,step 屬性的符號指定軸的方向。否則,direction_cosines 確定資料相對於世界座標系的定向,即 direction_cosine 為 (0.9, 0.43589, 0)。有關詳細公式,請參考 Robert D. Vincent 撰寫的《MINC 2.0 檔案格式》第 2.1 節。
基本 MINC 軟體發行版中包含的核心工具具有一些共同的特點。首先,它們都可以在任何 MINC 檔案上正常執行,無論其維度或資料型別如何。其次,它們作為 UNIX “命令列” 工具實現,沒有圖形使用者介面。雖然這可能會使工具學習起來有些困難,但它也具有易於構建更復雜的應用程式的優勢,這些應用程式可以在指令碼語言或批處理程式設計環境中呼叫這些工具。最後,這些工具的設計使得輸入檔案永遠不會被修改:任何 MINC 工具的結果,如果適用,總是會生成一個或多個新的 MINC 檔案。
MINC 工具使用大量有時令人困惑的命令列選項來控制工具的行為。本節將嘗試解釋一些更常見的命令列選項,而不是單獨處理每個工具。
大多數選項以單個“破折號”字元開頭。
這些命令列選項中的許多都有預設值,因此,如果您沒有顯式指定值,程式將假設您希望使用“正常”行為。下面每個條目中以粗體顯示的都是預設選項。
-version- 此選項將導致工具列印其版本號並退出。不會執行其他操作。-help- 此選項要求工具列印其識別的所有選項的摘要,並簡要描述每個選項。-noclobber和-clobber- 這些選項控制 MINC 工具是否會覆蓋現有的輸出檔案。所有 MINC 工具的正常行為是拒絕替換現有檔案。
例如,如果您已經在與 'input.mnc' 相同的目錄中有一個名為 'test.mnc' 的檔案,並且您鍵入以下內容
mincreshape -transverse -noclobber input.mnc test.mnc
程式將拒絕執行,因為這樣做會破壞現有的 test.mnc 檔案。如果您指定 -clobber 選項,程式將用新的輸出檔案替換現有檔案。
-quiet和-verbose- 指定 '-verbose' 將導致程式列印更廣泛的中間操作和計算列表,這可能有助於除錯。指定 '-quiet' 將抑制大多數這些訊息。-2- 此選項告訴程式生成 MINC 2 格式的輸出檔案。
新工具 'mincconvert' 已建立用於在 MINC 1 和 MINC 2 格式之間進行轉換。要將 MINC 1 檔案轉換為 MINC 2 檔案,您可以像這樣使用 mincconvert
mincconvert -2 input.mnc output.mnc
要從 MINC 2 轉換回 MINC 1 格式,請省略 '-2' 選項
mincconvert input.mnc output.mnc
對於從 Analyze 或 DICOM 等其他格式轉換為 MINC 2,可能需要先轉換為 MINC 1 格式,然後使用 mincconvert 從 MINC 1 轉換為 MINC 2。此限制將在這些轉換指令碼的未來版本中刪除。
每個核心 MINC 工具現在都會自動檢測 MINC 1 或 MINC 2 檔案作為輸入檔案,並且在任一情況下都能正常工作。
此外,每個可以生成 MINC 檔案作為輸出的核心 MINC 工具現在都接受 '-2' 選項來指示需要 MINC 2 格式的輸出。
影像幾何和離散化
mincreshape- 此工具用於重新構造 MINC 檔案中的資料。它可以用於提取資料的子集,或重新排序資料中的維度。它不會修改資料的縮放,也不會更改檔案的世界座標系。執行維度長度更改,但是這些更改是使用非常簡單的體素平均或加倍來實現的。對於更復雜的 檔案重塑,請參見mincresample。mincresample- 此工具用於在 MINC 檔案上應用任意座標轉換。可以執行三三次、三線性或最近鄰插值。mincconcat- 此工具將沿特定軸連線任意數量的 MINC 檔案,生成單個輸出檔案。
體素計算
mincmath- 對一個或多個 MINC 檔案執行簡單的“體素”數學運算。例如,mincmath可用於將兩個體積相加,將常數新增到體積,計算體積的平方或倒數等。mincstats- 計算 MINC 檔案的一些基本統計特徵。這些包括體素計數、體積、全域性最小值和最大值、總和、方差、標準差等。mincstats還可以計算和儲存直方圖以及與直方圖相關的統計資料。minccalc- 與mincmath類似,minccalc可以執行更廣泛、更復雜的涉及一個或多個 MINC 檔案的體素數學運算。mincaverage- 從多個輸入體積計算平均 MINC 體積。minclookup- 對 MINC 檔案執行“查詢表”轉換,根據任意函式將值替換為新值。例如,檔案可以轉換為灰度、光譜 RGB 值。mincmakescalar- 透過選擇或組合向量元素將向量影像轉換為標量影像。mincmakevector- 將一組標量影像轉換為單個向量影像。
實用函式
mincinfo- 從 MINC 檔案列印任意一組標頭欄位。mincheader- 列印 MINC 檔案的所有標頭資訊。minc_modify_header- 更改 MINC 檔案中的單個屬性。這對於新增或更改支援資訊或更正座標資訊而不更改資料很有用。但是,此工具應謹慎使用,因為它會直接更改檔案的標頭,並且不會建立備份。mincedit- 編輯 MINC 檔案。MINC 檔案被轉換為文字表示形式,該表示形式會自動載入到文字編輯器中。當用戶完成編輯會話時,文字表示形式將轉換回 MINC 格式。原始檔案的備份副本將被保留。mincview- 檢視 MINC 檔案。minchistory- 列印 MINC 檔案的“歷史記錄”屬性,該屬性提供用於生成此檔案的命令的審計跟蹤。mincdiff- 顯示兩個 MINC 檔案之間的差異。minccopy- 將資料從一個 MINC 檔案複製到另一個檔案。
基本檔案格式轉換
mincconvert- 用於將 MINC 1 檔案轉換為 MINC 2 檔案,反之亦然。minctoraw- 將 MINC 檔案轉換為原始資料檔案。原始資料檔案是一個僅包含體素值的檔案,這些值儲存在井然有序的排列中。rawtominc- 將原始資料檔案轉換為 MINC 檔案。mincextract- 提取 MINC 檔案資料的任意塊。mincpik- 從 MINC 檔案生成圖形影像。
擴充套件檔案格式轉換
ecattominc- 將 ECAT 影像資料轉換為 MINC 格式。minctoecat- 將 MINC 影像資料轉換為 ECAT 格式。nii2mnc- 將 NIfTI-1 和 Analyze 影像資料轉換為 MINC 格式。mnc2nii- 將 MINC 影像資料轉換為 NIfTI-1 或 Analyze 格式。upet2mnc- 將微型 PET 影像資料轉換為 MINC 格式。
視覺化
MNI Register- 一個視覺化程式,支援透過對兩個顯示影像上的同源點進行標記來進行影像配準。MNI Display- 一個複雜的視覺化程式,支援顯示體素和 3D 表面影像資料。xdisp- 用於視覺化動態影像的程式。postf- 用於視覺化動態影像的非常簡單的程式。
資料模擬
mrisim- 用於生成高度逼真的模擬解剖學 MRI 影像的工具。
影像配準
mni_autoreg- 用於計算變換以將兩個 MRI 體積配準或將一個 MRI 體積配準到標準座標空間的工具。
強度歸一化
N3- 非引數非均勻強度歸一化提供了一種方法,用於自動校正由於射頻場不均勻性、渦流和/或患者解剖結構導致的 MRI 影像強度平滑變化。
組織分類
classify- 分類提供各種基於影像強度的體素級標籤演算法。包含有監督和無監督分類器。
其他可用的工具仍在開發中
mincdti- 從 MINC 影像計算擴散張量。mincfft- MINC 影像的快速傅立葉變換。mincmorph- 執行標準影像處理操作:膨脹、腐蝕、高通、低通、鉗位、二值化、卷積等。mincsample- 在可選掩模體積的情況下,從一個或多個 MINC 檔案中提取隨機子樣本。volregrid-
哪裡可以獲得更多資訊
[edit | edit source]您可以從兩個來源獲得有關每個核心 MINC 工具的更多資訊。每個工具都有一個 UNIX 'man' 頁面,它對工具的功能以及控制其行為的選項進行了詳細的解釋。
要檢視工具選項的簡要列表,請在命令中使用 -help 選項。
使用 MINC 2 庫
[edit | edit source]程式設計師可以使用 MINC 2 庫來建立操作 MINC 檔案的新程式。該庫是為與 'C' 程式語言一起使用而設計和編寫的。無需瞭解 HDF5 或 NetCDF 即可使用 MINC 2 庫。
本文件無法全面解釋庫的所有功能。有關 MINC 2 程式設計介面的詳盡參考,請參閱文件 MINC 2.0 Programmer's Reference Manual。
標頭檔案和庫檔案
[edit | edit source]透過在原始檔中包含檔案 'minc2.h' 並在 libminc2.a 庫中連結,MINC 2 庫可以包含在任何 C 或 C++ 程式中。這可以透過大多數 UNIX 連結工具完成,方法是在編譯器的連結選項中新增以下內容
-lminc2 -lhdf5 -lnetcdf
要構建 MINC 2 程式,必須顯式地與 HDF5 庫和 NetCDF 庫連結。
函式返回值
[edit | edit source]大多數 MINC 2 庫函式返回一個帶符號的整數值,該值報告操作是成功(MI_NOERROR)還是失敗(MI_ERROR)。更一般地說,負返回值被解釋為錯誤結果,而零或正返回值被解釋為表示操作成功。
開啟和關閉體積
[edit | edit source]可以使用函式呼叫開啟 MINC 2 體積
miopen_volume(const char *path, int mode, mihandle_t *hvol);
path 引數給出要訪問的檔案的絕對或相對路徑名。
mode 引數控制檔案是僅以只讀方式開啟(MI2_OPEN_RDONLY)還是以讀寫方式開啟(MI2_OPEN_RDWR)。
檔案 'handle' 在後續檔案操作中必須使用,它在 hvol 引數中返回。程式使用完檔案後,應透過呼叫關閉檔案並釋放檔案控制代碼
miclose_volume(mihandle_t hvol);
以下是一個展示這兩個函式用法的示例
#include <minc2.h>
main() {
int result;
mihandle_t hvol;
result = miopen_volume("/home/sparky/test.mnc",
MI_OPEN_RDONLY, &hvol);
if (result != MI_NOERROR) {
fprintf(stderr, "Error opening the input file.\n");
}
/* Work with the file here. */
miclose_volume(hvol);
}
資料型別
[edit | edit source]型別
[edit | edit source]這些型別指的是資料在檔案中的儲存格式。在某些情況下,可能會應用額外的縮放或其他轉換,具體取決於體積的類別。
- MI_TYPE_BYTE - 8 位帶符號整數。
- MI_TYPE_SHORT - 16 位帶符號整數。
- MI_TYPE_INT - 32 位帶符號整數。
- MI_TYPE_FLOAT - 32 位浮點數。
- MI_TYPE_DOUBLE - 64 位浮點數。
- MI_TYPE_STRING - ASCII 字串。
- MI_TYPE_UBYTE - 8 位無符號整數。
- MI_TYPE_USHORT - 16 位無符號整數。
- MI_TYPE_UINT - 32 位無符號整數。
- MI_TYPE_SCOMPLEX - 16 位帶符號整數複數
- MI_TYPE_ICOMPLEX - 32 位帶符號整數複數
- MI_TYPE_FCOMPLEX - 32 位浮點數複數
- MI_TYPE_DCOMPLEX - 64 位浮點數複數
- MI_TYPE_UNKNOWN - 用於記錄或陣列型別。
類別
[edit | edit source]體積的類別描述瞭如何解釋體素資料。最典型的情況是體積具有整數型別,但類別值為 'real'。這對應於典型的 MINC 1 檔案,該檔案定義了縮放
- MI_CLASS_REAL - 浮點數。資料將被解釋為浮點數,無論儲存型別如何。可用於任何整數或浮點數型別。
- MI_CLASS_INT - 整數。資料將被解釋為整數值。可用於任何整數型別。
- MI_CLASS_LABEL - 標記或列舉資料。假設體素的值來自一個離散集。這些值可以分配符號名稱來澄清資料的解釋。可用於任何整數型別。
- MI_CLASS_COMPLEX - 具有實部和虛部的複數資料。只能用於複數型別(整數或浮點數)之一。
- MI_CLASS_UNIFORM_RECORD - 統一記錄結構,本質上是一個帶有命名條目的陣列。
- MI_CLASS_NON_UNIFORM_RECORD - 非統一記錄結構。這尚未實現。
維度和座標系
[edit | edit source]維度定義
[edit | edit source]維度只是一個軸或索引,資料沿其儲存。典型的掃描可能是二維或三維,而功能資料可能儲存在一個四維檔案中,其中包含三個空間維和一個時間維。
MINC 2.0 維度
[edit | edit source]MINC 影像體積/檔案的每個維度都由其 name 指定。MINC2 定義了標準命名約定,例如 xspace, yspace, zspace(空間維度)、xfrequency, yfrequency, zfrequency(空間頻率維度)、tfrequency(時間頻率維度)、time(時間維度)以及最後 vector-dimension(請參閱第 1.2 節)。
重要的是要注意,在 MINC 2 中,某些預設解釋和屬性與標準命名維度相關聯。但是,這不會對 MINC 2 維度定義施加任何限制,因為使用者可以自由地為每個維度定義新的名稱、解釋和屬性。
維度屬性
[edit | edit source]每個維度都有一個 class,它指定其整體解釋:空間、時間、空間頻率、時間頻率或使用者定義(即任意)維度。以下是 minc 2 中定義的維度類別列表。
- MI_DIMCLASS_ANY - 不關心(或未知)
- MI_DIMCLASS_SPATIAL - 空間
- MI_DIMCLASS_TIME - 時間
- MI_DIMCLASS_SFREQUENCY - 空間頻率
- MI_DIMCLASS_TFREQUENCY - 時間頻率
- MI_DIMCLASS_USER - 使用者定義的任意軸
- MI_DIMCLASS_RECORD - 記錄作為維度
以上定義還建立了一個更靈活的命名約定,其中任何名稱都可以定義為任何維度類別。
除了name和class,MINC 2 還為每個維度定義了許多其他屬性,這些屬性指定了資料的解釋方式。
description屬性用於指定人類可讀的文字,該文字提供有關維度解釋的一些資訊。例如,它通常用於描述維度的方向相對於患者。description屬性僅針對命名維度xspace、yspace、zspace設定為預設文字,但使用者可以為任何維度設定該屬性。例如,xspace定義為從患者的左側增加到右側。
unit屬性也是人類可讀的文字,它定義了沿每個維度取樣資料點之間的距離單位。預設的unit屬性設定為毫米(即“mm”)。
spacing維度屬性是人類可讀的文字,它定義了取樣資料點在空間中彼此之間的間隔是恆定的還是隨機的(即規則的與不規則的)。spacing屬性預設設定為'regular__'。
start屬性是一個數字,它指定了第一個取樣資料點在世界座標系中的位置(參考體素與世界子節)。此屬性預設設定為零。step屬性是一個正數,表示沿規則取樣維度的取樣資料點之間的間隔大小。負值僅表示取樣資料點具有相反的方向。此屬性預設設定為 1。不規則取樣維度必須定義為每個取樣資料點對定義的間隔值列表,這在 MINC 2 中定義為offset屬性。
length屬性是一個數字,定義了沿維度的取樣資料點的總數。direction_cosines屬性是一組與空間維度關聯的三個向量,定義了軸相對於“真實” x、y 或 z 座標的精確方向。有關維度屬性的完整列表,請參閱MINC2.0 PI,網址為http://www.bic.mni.mcgill.ca/software/minc2/api_doc/minc_20.html
MINC 2 檔案可以定義任意數量的維度。在 MINC 2 庫中,維度由一個稱為維度控制代碼的不透明資料型別表示,它由'C' typedef midimhandle_t定義。透過使用維度控制代碼,使用者可以訪問和修改所有維度屬性。
在建立新維度之前,必須指定四個基本屬性。其他屬性將設定為預設值,這些預設值可以在建立維度後單獨更改。
micreate_dimension(const char *name, midimclass_t class,
midimattr_t attr,unsigned long length,
midimhandle_t *new_dim_ptr);
訪問或修改任何維度屬性都是透過使用以下方法完成的
miget_dimension_ property() miset_dimension_ property()
其中'property'可以替換為任何維度屬性。例如,
miget_dimension_units(midimhandle_t dimension,
char **units_ptr);
miset_dimension_units(midimhandle_t dimension,
const char *units);
可以使用以下函式檢索與開啟的 MINC 檔案關聯的維度
miget_volume_dimensions(mihandle_t hvol, midimclass_t class,
midimattr_t attr, miorder_t order,
int max_dims, midimhandle_t dims[]);
其中 miorder_t 是一個列舉型別標誌,它確定維度順序是透過檔案(即維度建立的順序)還是透過明顯順序(即除檔案順序之外的任何順序)來確定的,必須由使用者設定。
最後,要釋放與維度關聯的記憶體,必須將維度控制代碼傳遞給mifree_dimension_handle()。請注意,對與體積關聯的維度呼叫mifree_dimension_handle()會導致錯誤。
mifree_dimension_handle(midimhandle_t dim_ptr)
由於 MINC 檔案可以任意組織資料,因此 MINC 2.0 程式設計介面允許程式設計師指定維度的明顯順序和每個維度的明顯方向。這使程式能夠以最方便的方式指定排序,以便資料可以以任何方式呈現。
程式設計師可以為給定體積設定“明顯”維度順序。指定明顯維度順序會導致庫將所有座標和資料轉換為資料儲存在明顯順序中的樣子。如果一組必須同時處理的三個體積的維度分別是 x、y、z、z、y、x 和 y、z、x,那麼程式將它們都視為資料以 z、y、x 順序儲存可能會很有用。
轉換資料塊的維度會導致資料塊在讀取後或寫入之前在記憶體中重新構造。顯然,這種重新構造需要時間,會影響資料吞吐量。
如果明顯的維度順序恰好與體積的檔案維度順序匹配,則不會執行任何特殊處理。
對於每個維度,程式設計師還可以指定一個明顯方向。此明顯方向可以透過以下四種方式之一來指定
- 原生檔案順序 - 維度的方向與其在檔案中的顯示方式完全相同。
- 反檔案順序 - 維度的方向與檔案順序相反。
- 正向順序 - 世界座標系中維度的方向保證沿增加的體素座標為正。此模式僅在步長為負時反轉維度。
- 負向順序 - 世界座標系中維度的方向保證沿增加的體素座標為負。此模式僅在步長為正時反轉維度。
屬性是小型資料集、文字或數字,用於描述附加到它們的變數的額外資訊,並且不包含有關醫學影像本身的任何資訊。
history和title等屬性包含有關整個 MINC 檔案的資訊,並附加到“minc-2.0”組本身。其他屬性(如vartype和version)不包含有關影像的任何資訊,但支援它們附加到的變數,例如/minc-2.0/dimensions/xpsace/vartype。最後,屬性(如valid_range)提供有關影像資料的其他資訊,例如/minc-2.0/image/0/image/valid_range。有關屬性及其定義的完整列表,請參閱 Robert D. Vincent 編寫的MINC 2.0 檔案格式的第 4 節。
MINC 2 庫定義了一組用於操作屬性的函式。要設定屬性的值並建立它(如果它尚不存在),請使用以下方法
miset_attr_values(mihandle_t volume,
mitype_t attr_data_type,
const char *path,
const char *name,
int length, void *values)
其中檔案控制代碼、資料型別、屬性路徑(即在層次結構中建立此屬性的位置,/minc-2.0/history)、屬性的名稱、其長度(即 100 個字元)以及屬性的值作為引數傳遞。屬性的值使用以下方法檢索,
miget_attr_values(mihandle_t volume,
mitype_t attr_data_type,
const char *path,
const char *name,
int length, void *values)
最後,要刪除屬性,請使用
midelete_attr(mihandle_t volume,
const char *path, const char *name)
提供了幾個用於在 MINC 檔案中讀取和寫入資料的函式。
函式可以根據兩組標準分為四類。
首先,某些函式操作單個體素,而其他函式操作“超立方體”資料,該資料可以是任何大小和維數,直至整個檔案大小。
其次,某些函式讀取或寫入“原始”或“體素”資料,而其他函式操作“真實”資料。真實資料是根據影像的體素和真實範圍縮放的資料。
通常,以大塊而不是單個體素讀取和寫入檔案效率更高,因此,如果速度對您的應用程式很重要,最好避免使用單個體素函式。
所有超立方體操作都需要程式設計師指定超立方體的起點和大小。這些引數以陣列形式傳遞。start[](有時稱為voxel_offsets[])陣列指定超立方體的起點。它可以被認為是體素維度中距離真實起點(0,0,0)最近的點。count[](有時稱為sizes[])陣列指定沿每個維度所需超立方體的長度。
邏輯上,count[] 陣列中的任何值都不應該為零,因為這會導致超立方體總體積為零。換句話說,你將不會讀取任何資料。
另一個約束是 start 值加上 count 值必須始終小於或等於體素維度中的長度。
每個體素讀寫函式都假設 start[] 和 count[] 陣列中指定的座標和長度以“表觀”順序排列。預設情況下,表觀順序與檔案順序相同。
舉個例子,假設你有一個四維檔案,其結構根據維度 xspace、time、zspace、yspace 組織,它們的長度分別設定為 X、T、Z 和 Y。
我們使用 miset_apparent_dimension_order_by_name 為這些維度分配一個更傳統的順序
static char *dimorder[] = { "time", "zspace","yspace","xspace" }
miset_apparent_dimension_order_by_name(hvolume, 4, dimorder);
現在假設我們想在一個操作中讀取整個檔案。為此,我們可以設定以下內容
unsigned long start[4], count[4];
short buffer[T][Z][Y][X];
start[0] = start[1] = start[2] = start[3] = 0;
count[0] = T;
count[1] = Z;
count[2] = Y;
count[3] = X;
miget_voxel_value_hyperslab(hvolume, MI_TYPE_SHORT, start, count, buffer);
或者,我們可能只想要將來自一個時間位置的資料讀入一個三維陣列
unsigned long start[4], count[4];
short buffer[Z][Y][X];
start[0] = t; /* The desired time value */
start[1] = start[2] = start[3] = 0;
count[0] = 1;
count[1] = Z;
count[2] = Y;
count[3] = X;
miget_voxel_value_hyperslab(hvolume, MI_TYPE_SHORT, start, count, buffer);
另一種可能性是讀取特定空間位置的整個時間序列
unsigned long start[4], count[4];
short buffer[T];
start[0] = 0; /* Start at time=0 */
start[1] = z; /* z,y,x = spatial coordinate */
start[2] = y;
start[3] = x;
count[0] = T;
count[1] = count[2] = count[3] = 1;
miget_voxel_value_hyperslab(hvolume, MI_TYPE_SHORT, start, count, buffer);
體素轉換的詳細資訊
[edit | edit source]從真實資料到體素資料的轉換,或從體素資料到真實資料的轉換,可以用以下關係表示
其中 R(c) 是影像在座標位置 c 的真實值,而 V(c) 是影像在相同座標位置的體素值。 和 值對應於最大和最小真實值,它們也可能是位置的函式,儘管在更低維度上是如此。 和 對整個體積是全域性的,不會隨位置而變化。
有關這些縮放值的更多資訊,請參閱以下函式
int miget_volume_valid_range(mihandle_t volume,
double *valid_max,
double *valid_min);
int miget_slice_range(mihandle_t volume,
const unsigned long location[],
double *slice_max,
double *slice_min);
單個體素,體素資料函式
[edit | edit source] miget_voxel_value(mihandle_t volume,
const unsigned long location[],
double *voxel_ptr);
miset_voxel_value(mihandle_t volume,
const unsigned long location[],
double voxel);
這兩個函式讀取或寫入單個體素,座標由 location 陣列給出。location 陣列的長度必須等於體積中的維度數量。對資料執行的唯一轉換將是值保留的表示形式更改。如果實際儲存型別無法表示傳遞給 miset_voxel_value() 函式的值,則儲存的值將是未定義的。
單個體素,真實資料函式
[edit | edit source] int miget_real_value(mihandle_t volume,
const unsigned long location[],
double *value_ptr);
int miset_real_value(mihandle_t volume,
const unsigned long location[],
double value);
這兩個函式讀取和寫入單個體素,同時執行上述資料轉換。
超立方體,體素資料函式
[edit | edit source] int miget_voxel_value_hyperslab(mihandle_t volume,
mitype_t buf_type,
const unsigned long start[],
const unsigned long count[],
void *buf_ptr);
int miset_voxel_value_hyperslab(mihandle_t volume,
mitype_t buf_type,
const unsigned long start[],
const unsigned long count[],
const void *buf_ptr);
這兩個函式從檔案中讀取和寫入一個超立方體資料,對單個體素不執行任何資料轉換。座標轉換可能會執行,具體取決於體積維度和體素的表觀方向和順序。
超立方體,真實資料函式
[edit | edit source] int miget_real_value_hyperslab(mihandle_t volume,
mitype_t buf_type,
const unsigned long start[],
const unsigned long count[],
void *buf_ptr);
miget_real_value_hyperslab 從 MINC 檔案中檢索選定的超立方體資料。如果檔案的類是“real”,則每個體素都會透過使用儲存的影像最小值和最大值對其進行縮放來轉換。如果檔案的類不是“real”,則不會執行任何轉換。
int miset_real_value_hyperslab(mihandle_t volume,
mitype_t buf_type,
const unsigned long start[],
const unsigned long count[],
const void *buf_ptr);
miset_real_value_hyperslab 將選定的超立方體資料儲存到 MINC 檔案。如果檔案的類是“real”,則每個體素都會透過使用儲存的影像最小值和最大值對其進行縮放來轉換。如果檔案的類不是“real”,則不會執行任何轉換。
int miget_hyperslab_normalized(mihandle_t volume,
mitype_t buffer_data_type,
const unsigned long start[],
const unsigned long count[],
double min,
double max,
void *buffer);
miget_hyperslab_normalized 從檔案中讀取資料超立方體。除了執行標準轉換之外,資料還被規範化,使得值被對映到指定 buffer_data_type 的完整範圍內,使得小於或等於 min 的真實體素值將被對映到資料型別可能的最低值,而大於或等於 max 的真實體素值將被對映到資料型別可能的最高值。
在所有必需的維度控制代碼被定義/分配了它們適當的類別和屬性之後,可以透過呼叫以下函式建立 MINC 2.0 檔案
micreate_volume(const char *filename,
int number_of_dimensions,
midimhandle_t dimensions[],
mitype_t volume_type,
miclass_t volume_class,
mivolumeprops_t create_props,
mihandle_t *volume)
其中 filename、維度數量、維度控制代碼陣列、體積型別、體積類別和最後體積屬性是給定的引數,檔案控制代碼將在檔案成功建立後作為檢索引數。micreate_volume 建立檔案模板(即關於實際影像、其維度等的全部資訊),但不建立實際的影像檔案本身。要為檔案建立實際影像,在建立檔案模板後使用以下函式
micreate_volume_image(mihandle_t volume)
其中控制代碼是由呼叫前一個函式檢索到的。以下是一個展示這兩個函式用法的示例
#include <minc2.h>
main() {
int result;
mihandle_t hvol;
midimhandle_t dim[3];
mivolumeprops_t props;
result = minew_volume_props(&props);
result = miset_props_compression_type(props,
MI_COMPRESS_ZLIB);
result = miset_props_zlib_compression(props, 3);
result = miset_props_multi_resolution(props, 1, 3);
if (result < 0) {
TESTRPT("failed", result);
}
result = micreate_dimension("xspace",MI_DIMCLASS_SPATIAL,
MI_DIMATTR_REGULARLY_SAMPLED,
10,&dim[0]);
if (result < 0) {
TESTRPT("failed", result);
}
result = micreate_dimension("yspace",MI_DIMCLASS_SPATIAL,
MI_DIMATTR_REGULARLY_SAMPLED,
10,&dim[1]);
if (result < 0) {
TESTRPT("failed", result);
}
result = micreate_dimension("zspace",MI_DIMCLASS_SPATIAL,
MI_DIMATTR_REGULARLY_SAMPLED,
6,&dim[2]);
if (result < 0) {
TESTRPT("failed", result);
}
result = micreate_volume("test_multi_h5.mnc", 3, dim,
MI_TYPE_UINT, MI_CLASS_REAL,
props,&hvol);
if (result < 0) {
TESTRPT("failed", result);
}
result = micreate_volume_image(hvol);
if (result < 0) {
TESTRPT("failed", result);
}
}
分塊,也稱為分塊,是指組織影像資料儲存的另一種方法。大多數標準作業系統將檔案表示為一個一維的八位位元組陣列。在傳統的檔案中,多維資料儲存在一個簡單的連續值陣列中。每個連續的值與前一個值相關聯,透過檔案“變化最快”的維度的增量來確定,該維度通常是最後一個維度。第一個維度是檔案“變化最慢”的維度。例如,給定一個具有維度,,和 的三維影像,長度為 , , 和 ,任何位於位置 的體素的正確儲存索引可以計算為
這種儲存方法具有簡單性的優點,並且也方便地模擬了“C”程式語言中陣列的記憶體組織。但是,它有兩個主要缺點。首先,它假設所有資料都儲存在一個連續的塊中。這降低了靈活性,例如,使得實現資料壓縮變得極其困難,因為壓縮可能會消除相鄰資料值之間可預測的關係。其次,這種儲存方法本質上有利於沿變化最快維度讀取整個部分的輸入和輸出。在上面的示例中,如果你的程式想要讀取一個在 $x$ 和 $y$ 中變化但在固定 $z$ 處的切片資料,它必須讀取大部分檔案以收集所需資料。
在啟用“阻塞”的檔案中,資料以更復雜的方式儲存。定義了一個與整個檔案具有相同維度的塊,每個塊包含整個資料中的固定大小的塊。例如,如果一個檔案的總體維度為,而塊大小為,則檔案的資料將被分組到 1000 個數據塊中,每個塊包含 1000 個值。第一個塊包含所有資料點 ,,和 。在塊內,儲存佈局與上述連續情況相同。
為了使事情更復雜,檔案可能包含某種轉換表,該表定義了每個塊的物理儲存位置,因此塊可能不會按特定順序儲存。
塊結構檔案的優點是,透過使系統擺脫嚴格排序的儲存方式,每個塊的位置和大小可以有所不同。如果應用壓縮演算法,一些塊將被證明是高度可壓縮的,因此會非常小,而相對不可壓縮的塊將相對較大。在稀疏陣列的情況下,可能可以避免為僅包含預設值的塊分配空間。
作者
[edit | edit source]John G. Sled, Robert D. Vincent, Leila Baghdadi