1. 程式人生 > >NIFTI格式(.Nii)資料version 1格式分析

NIFTI格式(.Nii)資料version 1格式分析

NIFTI格式(.Nii)資料格式分析

NIFTI出現原因

  1. NIFTI出現的原因是原來一種影象格式是ANALYZE 7.5 format,但是這個影象格式缺少一些資訊,比如沒有方向資訊,病人的左右方位等,如果需要包括額外的資訊,就需要一個額外的檔案,比如ANALYZE7.5就需要一對<.hdr, .img>檔案來儲存影象的完整資訊。因此,解決這個問題Data Format Working Group (DFWG) 將影象格式完整的定義為NIFTI(Neuroimaging Informatics Technology Initiative)格式。
  2. 放射學和神經學醫生使用軟體和使用習慣會有一些不同,所以為了統一格式,DFWG提出NIFTI格式影象。
  3. NIFTI格式的讀取軟體,也應該可以讀取<.hdr, .img>檔案對。

NIFTI-1檔案頭資訊格式

  • :NIFTI格式中儲存的資訊是,一共可以儲存7維資料。第1,2,3維度(0維統計使用維度個數)保留給空間維度x,y,z,而第四維度留給時間維度t。第5,6,7維度可供使用者其他使用,但是第五維度也有一些預定義的用途,例如儲存特定體素分佈的引數或儲存向量資料。
// NIFTI version1 標頭檔案儲存資訊(順序存放)
/*
NIFTI 第一版的資料格式的標頭檔案大小必須為348位元組,這是為了相容新,和舊的analyze格式保持一致。就是sizeof_hdr儲存的資料大小。
*/
// //OFFSET SIZE Description int sizeof_hdr; //0B 4B Size of the header.Must be 348 (bytes). char data_type[10]; //4B 10B Not used; compatibility with analyze. char db_name[18]; //14B 18B Not used; compatibility with analyze. int extents; //32B 4B Not used; compatibility with analyze.
short session_error; //36B 2B Not used; compatibility with analyze. char regular; //38B 1B Not used; compatibility with analyze. char dim_info; //39B 1B Encoding directions(phase, frequency, slice). short dim[8]; //40B 16B Data array dimensions. float intent_p1; //56B 4B 1st intent parameter. float intent_p2; //60B 4B 2nd intent parameter. float intent_p3; //64B 4B 3rd intent parameter. short intent_code; //68B 2B nifti intent. short datatype; //70B 2B Data type. short bitpix; //72B 2B Number of bits per voxel. short slice_start; //74B 2B First slice index. float pixdim[8]; //76B 32B Grid spacings(unit per dimension). float vox_offset; /*108B 4B Offset into a.nii file. !Data true start point.*/ float scl_slope; //112B 4B Data scaling, slope. float scl_inter; //116B 4B Data scaling, offset. short slice_end; //120B 2B Last slice index. char slice_code; //122B 1B Slice timing order. char xyzt_units; //123B 1B Units of pixdim[1..4]. float cal_max; //124B 4B Maximum display intensity. float cal_min; //128B 4B Minimum display intensity. float slice_duration; //132B 4B Time for one slice. float toffset; //136B 4B Time axis shift. int glmax; //140B 4B Not used; compatibility with analyze. int glmin; //144B 4B Not used; compatibility with analyze. char descrip[80]; //148B 80B Any text. char aux_file[24]; //228B 24B Auxiliary filename. short qform_code; //252B 2B Use the quaternion fields. short sform_code; //254B 2B Use of the affine fields. float quatern_b; //256B 4B Quaternion b parameter. float quatern_c; //260B 4B Quaternion c parameter. float quatern_d; //264B 4B Quaternion d parameter. float qoffset_x; //268B 4B Quaternion x shift. float qoffset_y; //272B 4B Quaternion y shift. float qoffset_z; //276B 4B Quaternion z shift. float srow_x[4]; //280B 16B 1st row affine transform float srow_y[4]; //296B 16B 2nd row affine transform. float srow_z[4]; //312B 16B 3rd row affine transform. char intent_name[16];//328B 16B Name or meaning of the data. char magic[4]; //344B 4B Magic string.

檔案的讀取器需要的重要引數包括:

sizeof_hdr, dim[8], datatype, bitpix, pixdim[8], vox_offset. 

各個頭欄位內容和意義

int sizeof_hdr

sizeof_hdr 是儲存檔案的標頭檔案大小,如果是NIFTI-1或者ANALYZE格式的檔案sizeof_hdr=348.

  • 注:從 data_type[10] 到 regular 欄位,在NIFTI檔案中沒有使用,僅僅是為了和ANALYZE格式相容。

char dim_info

dim_info欄位儲存著頻率編碼方向(1,2,3),相位編碼方向(1,2,3)和採集期間層選擇方向(1,2,3),對於徑向採集來講,頻率編碼和相位編碼都設定為0。

short dim[8]

short dim[8]儲存著前面提到的影象的維度資訊。如果第0維不是(1-7)之間的數字,那麼這個資料具有相反的位元組順序,所以應該進行位元組交換(NIFTI標準沒有提供位元組順序的欄位,提倡使用dim[0])。

intent系列(影響到影象資料的讀取和儲存)

short intent_code是一個編碼後的整數碼。一些程式碼包括需要額外的引數,比如自由度數。這些額外的資訊當需要的時候可以儲存在intent_p1, _p2, _p3這些欄位內,或者如果voxelwise,則儲存在第五維中。如下列表中是intent編碼:

INTENT                      CODE        PARAMETERS
None                        0           no parameters
Correlation                 2           p1 = degrees of freedom (df)
t test                      3           p1 = df
F test                      4           p1 = numerator df, p2 = denominator df
z score                     5           no parameters
χ^2statistic                6           p1 = df
Beta distribution           7           p1 = a, p2 = b
Binomial distribution       8           p1 = number of trials, p2 = probability per trial
Gamma distribution          9           p1 = shape, p2 = scale
Poisson distribution        10          p1 = mean
Normal distribution         11          p1 = mean, p2 = standard deviation
Noncentral F statistic      12          p1 = numerator df, p2 = denominator df, p3 = numerator noncentrality parameter
Noncentral χ2 statistic     13          p1 = dof, p2 = noncentrality parameter
Logistic distribution       14          p1 = location, p2 = scale
Laplace distribution        15          p1 = location, p2 = scale
Uniform distribution        16          p1 = lower end, p2 = upper end
Noncentral t statistic      17          p1 = dof, p2 = noncentrality parameter
Weibull distribution        18          p1 = location, p2 = scale, p3 = power
χ distribution              19          p1 = df*
Inverse Gaussian            20          p1 = μ, p2 = λ
Extreme value type I        21          p1 = location, p2 = scale
p-value                     22          no parameters
-ln(p)                      23          no parameters
-log(p)                     24          no parameters
//一下編碼代表檔案中包含一些不是統計特性的資料
Estimate                    1001        Estimate of some parameter, possibly indicated in intent_name
Label                       1002        Indices of a set of labels, which may be indicated in aux_file.
NeuroName                   1003        Indices in the NeuroNames set of labels.
Generic matrix              1004        For a MxN matrix in the 5th dimension, row major. p1 = M, p2 = N (integers as float); dim[5] = M*N.
Symmetric matrix            1005        For a symmetric NxN matrix in the 5th dimension, row major, lower matrix. p1 = N (integer as float); dim[5] = N*(N+1)/2.
Displacement vector         1006        Vector per voxel, stored in the 5th dimension.
Vector                      1007        As above, vector per voxel, stored in the 5th dimension.
Point set                   1008        Points in the space, in the 5th dimension. dim[1] = number of points; dim[2]=dim[3]=1; intent_name may be used to indicate modality.
Triangle                    1009        Indices of points in space, in the 5th dimension. dim[1] = number of triangles.
Quaternion                  1010        Quaternion in the 5th dimension.
Dimless 1011    Nothing. The intent may be in intent_name.
Time series                 2001        Each voxel contains a time series.
Node index                  2002        Each voxel is an index of a surface dataset.
rgb                         2003        rgb triplet in the 5th dimension. dim[0] = 5, dim[1] has the number of entries, dim[2:4] = 1, dim[5] = 3.
rgba                        2004        rgba quadruplet in the 5th dimension. dim[0] = 5, dim[1] has the number of entries, dim[2:4] = 1, dim[5] = 4.
Shape                       2005        Value at each location is a shape parameter, such as a curvature.

如果進行資料讀取,那麼在判斷資料大小時需要提取intent中的一些編碼方向和intent_p變數中儲存的資料大小。

比如,如果儲存的為generic matrix, 那麼dim中的資料就無法直接獲取資料的維度資訊,則需要在intent中獲得intent的code編碼,在從intent_p1和intent_p2中獲得矩陣的維度大小。

symmetric matrix的矩陣大小是N*N,那麼intent_p1=N,dim[5]=N*(N+1)/2.(對稱矩陣,只儲存一半矩陣值就可以,行排列優先)。

displacement vector(位移向量):每個畫素儲存一個向量大小值,儲存在第五維。

vector:和上邊唯一向量一樣。

point set:第一維中dim[1]=點的數量。dim[2]=dim[3]=1, 空間中的點存在第五維。

triangle:空間點的指數,儲存在第五維。dim[1]=triangles的數量。

Quaternion:在第五維中的四元組。

RGB:第五維中RGB三元組,dim[0]=5, dim[1]=entries數目,dim[2:4]=1,dim[5]=3

RGBA:第五維中是RGBA四元組,dim[0]=5, dim[1] = entries數目,dim[2:4]=1, dim[5]=4.

Data Type 和 bitpix(bits per pixel/voxel)

datatype中儲存的是資料的型別,可接受型別如下:

型別 bit(s)/pix CODE
unknown 0
bool 1 bit 1
unsigned char 8 bits 2
signed short 16 bits 4
signed int 32 bits 8
float 32 bits 16
complex 64 bits 32
double 64 bits 64
rgb 24 bits 128
“all” 255
signed char 8 bits 256
unsigned short 16 bits 512
unsigned int 32 bits 768
long long 64 bits 1024
unsigned long long 64 bits 1280
long double 128 bits 1536
double pair 128 bits 1792
long double pair 256 bits 2048
rgba 32 bits 2304

而bitpix欄位必須與datatype中的程式碼所對應的bit(s)/pix的大小相等。

slice切片資訊

包含欄位:slice_start,slice_end, slice_code, slice_duration

slice_duration是儲存功能磁共振成像採集的時間相關資訊,需要與dim_info欄位一起使用,dim_info有slice_dim資訊。有且僅有slice_dim不是0時,slice_info可以解釋為以下編碼:

CODE|       INTERPRETATION
--- |       ---
0   |       Slice order unknown
1   |       Sequential, increasing
2   |       Sequential, decreasing
3   |       Interleaved, increasing, starting at the 1st mri slice
4   |       Interleaved, decreasing, starting at the last mri slice
5   |       Interleaved, increasing, starting at the 2nd mri slice
6   |       Interleaved, decreasing, starting at one before the last mri slice

slice_duration是指湖區一單張影象所需時間。在單獨的區域將這些資訊儲存裝置相關的影象資訊要比儲存到pixdim[4]中要節約空間,slice_duration*dim[slice_dim]。
(說實話,不是很懂)

float pixdim[8] 體素維度

每個體素維度資訊都儲存在pixdim[8]中,各自對應dim[8],但pixdim[0]有特殊意義,其值只能是-1或1。前四個維度將在xyzt_units欄位中指定。

float vox_offset 體素偏移量

vox_offset指 單個檔案(.nii)影象資料的位元組偏移量。
為了相容老的軟體(好煩啊!!!)可能的值是16的倍數,最小值是352(因為標頭檔案就是348,所以最小隻能取352 Bytes)
如果是檔案對(.hdr/.img),vox_offset=0。但是也可以>0,那麼就是當用戶想要儲存額外的資訊在.img檔案中,就像DICOM檔案頭一樣。但是在檔案對中,如果vox_offset>0,那麼vox_offset是16的倍數就不用保障了。vox_offset的型別是float(32位)而非int是基於標頭檔案記憶體對齊以及和ANALYZE格式相容。

float scl_slope和scl_inter 資料縮放的斜率和截距

儲存在每個體素中的值可以線性縮放到不同的單位。欄位float scl_slope和float scl_inter定義一個斜率和一個線性函式的截距。資料縮放功能允許儲存在比資料型別所允許的範圍更廣的範圍內。但是,可以在相同的資料型別中使用縮放。對於rgb資料的儲存,兩個縮放欄位都應該被忽略。對於複雜型別,它應用於實部和虛部。

float cal_min和cal_max 資料顯示

儲存標量資料的檔案,這兩個欄位用來影象開啟時預設顯示範圍。體素值小於等於cal_min的畫素顯示為顯示範圍中的最小值(灰度範圍內通常為黑),大於等於cal_max的值顯示為顯示範圍中的最大值(通常為白色),注意:這裡並不是真實改變資料大小,而是改變顯示大小。

xyzt_units 度量單位

在dim[1]和dim[4]中用到的空間和時間測量單元(對應各自的pixdim[1]和pixdim[4]),編碼在xyzt_units欄位中,1-3 bit用來儲存空間維度,4-6 bit用來儲存時間維度,6-7 bit沒有使用。時間偏移量放在float toffset欄位中,xyzt_units十進位制編碼如下:

UNIT CODE
Unknown 0
Meter (m) 1
Milimeter (mm) 2
Micron (µm) 3
Seconds (s) 8
Miliseconds (ms) 16
Microseconds (µs) 24
Hertz (Hz) 32
Parts-per-million (ppm) 40
Radians per second (rad/s) 48

char descrip[80] 描述

該欄位char descrip[80]可以包含最多80個字元的文字。標準中沒有指定這個字串是否需要被空字元終止。大概是由應用程式來正確處理它。

Auxiliary file 附加檔案

包含額外資訊的補充檔案可放在該欄位中。

方向資訊

nifti格式比以前的ANALYZE格式最明顯的改進是能夠明確地儲存資訊的方向。標準中假定體素座標指的是每個體素的中心,而不是某個位置為中心。假定座標系為右手座標系:x正方向是右,y正方向是前,z正方向是上。而ANALYZE是左手座標系。nifti格式提供三種對映到傳統座標系的方法:第一種只是為了和ANALYZE相容,另外兩種可以共存,轉換為不同的座標系統。這些系統在short qform_code欄位和short sform_code欄位中指定。下表是其編碼值:

NAME CODE DESCRIPTION
unknown 0 Arbitrary coordinates. Use Method 1.
scanner_anat 1 Scanner-based anatomical coordinates.
aligned_anat 2 Coordinates aligned to another file, or to the “truth” (with an arbitrary coordinate center).
talairach 3 Coordinates aligned to the Talairach space.
mni_152 4 Coordinates aligned to the MNI space.

原則上,qform_code(下面的方法2)應包含0,1或2,而sform_code(下面的方法3)可以包含任何在表中所示的編碼。

char magic[4]

該字串宣告檔案符合NIFTI標準。
理想情況下,應該先檢查該欄位,如果欄位中儲存為”ni1”(或者是16進位制的‘6E 69 31 00’),那麼是.hdr/.img檔案對形式;如果是’n+1’(或’6E 2B 31 00’),那麼就是單一的.nii檔案;而如果缺少字串,那麼就按照ANALYZE格式處理。未來還會有’n+2’, ‘n+3’等字串對應於NIFTI的後續版本。

在該版本中未使用的區域

char data_type[10], char db_name[18], int extents, short session_error以及char regular在NIFTI-1中未被啟用,僅僅用來相容ANALYZE標準。extent欄位應該是整數16384,regular應該是字元’r’, glmin和glmax分別對應於ANALYZE格式中資料集中腦的最小和最大值。

儲存的額外資訊

按照標準有許多方式允許把額外的資訊包含到NIFTI格式中。在頭的最後,接下來的4個位元組(比如從349到352,352包含在內)可以也可以不在.hdr檔案中出現。然而,這4位元組在.nii檔案中一定存在。解析為一字元陣列,如char extention[4]。原則上這四個位元組都應該被置為0。如果首先extension[0]是非零的,意味著從353位元組開始是擴充套件資訊。擴充套件資訊的大小應該是16位元組的倍數,擴充套件的第一個8位元組,應該被解釋為兩個整數:int esize 和int ecode。esize欄位儲存擴充套件資訊的大小(這個大小包括esize和ecode本身佔用的8位元組。)
ecode欄位用來儲存剩下的額外資訊。已經定義的三個ecode編碼如下:

CODE USE
0 Unknown. This code should be avoided.
2 dicom extensions
4 xml extensions used by the AFNI software package.

在同一個檔案中可以擴充套件多個額外資訊,每一個擴充套件的額外資訊都必須以esize和ecode對開始,下一個額外資訊緊接著上一個額外資訊開始。在單一的.nii檔案中,vox_offset欄位必須設定為在最後一個額外資訊後的影象資料開始點。

第一個版NIFTI格式檔案的問題

The nifti format brought a number of great benefits if compared to the old analyze format. However, it also brought its own set of new problems. Fortunately, these problems are not severe. Here are some:

  • Even though a huge effort was done to keep compatibility with analyze, a crucial aspect was not preserved: the world coordinate system is assumed, in the nifti format, to be ras, which is weird and confusing. The las is a much more logical choice from a medical perspective. Fortunately, since orientation is stored unambiguously, it is possible to later flip the images in the screen at will in most software.
  • The file format still relies too much on the file extension being .nii or on a pair .hdr/.img, rather than much less ambiguous magic strings or numbers. On the other hand, the different magic strings for single file and for file pairs effectively prevent the possibility of file splitting/merging using common operating system tools (such as dd in Linux), as the magic string needs to be changed, even though the header structure remains absolutely identical.
  • The magic string that is present in the header is not placed at the beginning, but near its end, which makes the file virtually unrecognisable outside of the neuroimaging field.
  • The specification of three different coordinate systems, while bringing flexibility, also brought ambiguity, as nowhere in the standard there is information on which should be preferred when more than one is present. Certain software packages explicitly force the qform_code and sform_code to be identical to each other.
  • There is no field specifying a preferred interpolation method when using Methods 2 or 3, even though these methods do allow fractional voxels to be found with the specification of world coordinates.
  • Method 2 allows only rotation and translation, but sometimes, due to all sorts of scanner calibration issues and different kinds of geometric distortion present in different sequences, the coregistration between two images of the same subject may require scaling and shear, which are only provided in Method 3.
  • Method 3 is supposed to inform that the data is aligned to a standard space using an affine transformation. This works perfectly if the data has been previously warped to such a space. Otherwise, the simple alignment of any actual brain from native to standard space cannot be obtained with only linear transformations.
  • To squeeze information while keeping compatibility with the analyze format, some fields had to be mangled into just one byte, such as char dim_info and char xyzt_units, which is not practical and require sub-byte manipulation.
  • The field float vox_offset, directly inherited from the analyze format, should in fact, be an integer. Having it as a float only adds confusion.
  • Not all software packages implement the format exactly in the same way. Vector-based data, for instance, which should be stored in the 5th dimension, is often stored in the 4th, which should be reserved for time. Although this is not a problem with the format itself, but with the use made of it, easy implementation malpractices lead to a dissemination of ambiguous and ill-formed files that eventually cannot be read in other applications as intended by the time of the file creation.

Despite these issues, the format has been very successful as a means to exchange data between different software packages. An updated format, the nifti 2.0, with a header with more than 500 bytes of information, may become official soon.

原文地址