まずはSPMの話です。
脳画像の解像度を変更する場合は、SPMのreslice()を使って、と言うのが普通です。その場合、参照画像(Image Defining Space)とターゲット画像(Image to Reslice)の双方を指定します。GUI上でmat file(MATLABのバイナリーファイル)に保存することもあります。
あるいは、mファイル(テキストファイル)のスクリプトを実行することもできます。たとえば、次のような2種類のmファイルの形に保存して利用します。
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
<myreslice.mの例>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% List of open inputs
nrun = X; % enter the number of runs here
jobfile = {'D:\work\myreslice_job.m'};
jobs = repmat(jobfile, 1, nrun);
inputs = cell(0, nrun);
for crun = 1:nrun
end
spm('defaults', 'FMRI');
spm_jobman('run', jobs, inputs{:});
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
< myreslice_job.m の例>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%-----------------------------------------------------------------------
% Job saved on <date> by cfg_util (rev $Rev: 6460 $)
% spm SPM - SPM12 (6685)
% cfg_basicio BasicIO - Unknown
%-----------------------------------------------------------------------
matlabbatch{1}.spm.spatial.coreg.write.ref = {'D:\work\4D.nii,1'};
matlabbatch{1}.spm.spatial.coreg.write.source = {'D:\work\source.nii,1'};
matlabbatch{1}.spm.spatial.coreg.write.roptions.interp = 1;
matlabbatch{1}.spm.spatial.coreg.write.roptions.wrap = [0 0 0];
matlabbatch{1}.spm.spatial.coreg.write.roptions.mask = 0;
matlabbatch{1}.spm.spatial.coreg.write.roptions.prefix = 'l';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
以上はふだん良くやる常套手段ですが、あまり赤間は好みません。かといって、NipypeからSPMを呼び出すこともできますが、その場合はMATLABからは解放されないので、あまり意味はありません。
http://nipy.org/nipype/interfaces/generated/nipype.interfaces.spm.utils.html#reslice
などに詳しく書いてありますが、使ったことはありません。
実は、Nibabel(Access a cacophony of neuro-imaging file formats)とDipy(a free and open source software project for computational neuroanatomy, focusing mainly on DTI)を一緒に使うと、voxelサイズを指定するだけで簡単にresliceできるということがわかりました。
この手はあまりに簡単過ぎ(というかキレイすぎ)て、皆思いつかないかもしれないので、ここに掲載します。ぜひ試してみてください。
脳画像は、例によってNeurosynthから拾ってきます。
以下をipython上で実行します。元のvoxelサイズ2.0*2.0*2.0が3.0*3.0*3.0になります。FSLViewやSPMのDisplayなどで開いて確かめてみましょう。
関数化しようと思いますが、不適当な入力をはじく設定を入れようと考えています。
ipython上で実行する時は、以下をクリップボードにコピーし、
%paste
で一挙に実行してください。
なお、3Dのみならず、4DのNiiファイルでも確実に実行できることを確かめました。
ただ、Dipyの古いバージョンによっては、resliceというmoduleが存在しないとerrorが出ることがあります。またimage.headerが通らないことがあるので、#でコメントアウトした方が良いかもしれません。大きな4Dファイルはメモリを食いますので注意。
#######################################
#http://nipy.org/dipy/examples_built/reslice_datasets.html
#http://nipy.org/nibabel/nibabel_images.html
#Please refer to those pages.
import numpy as np
import nibabel as nib
from dipy.data import get_data
from dipy.align.reslice import reslice
img=nib.load('semantic_pFgA_z_FDR_0.01.nii.gz')#Change the file name.
img
#returns <nibabel.nifti1.Nifti1Image at 0x2d46b50>
#img.header
#returns <nibabel.nifti1.Nifti1Header at 0x2d46b90>
affine = img.get_affine()
affine
"""
Returns
array([[ -2., 0., 0., 90.],
[ 0., 2., 0., -126.],
[ 0., 0., 2., -72.],
[ 0., 0., 0., 1.]])
"""
zooms = img.get_header().get_zooms()[:3]
zooms
#Returns as always (2.0, 2.0, 2.0)
new_zooms = (3., 3., 3.)
new_zooms
#Returns (3.0, 3.0, 3.0)
data1=img.get_data()
#Using the function of dipy.data...
data2, affine2 = reslice(data1, affine, zooms, new_zooms)
#Using a function of dipy.align
data1.shape
#Returns(91, 109, 91), original size.
data2.shape
#Returns(61, 73, 61), new size.
img2 = nib.Nifti1Image(data2, affine2)
nib.save(img2, 'low_semantic_pFgA_z_FDR_0.01.nii.gz')#Change the file name here.
###############################