티스토리 뷰

일반적인 데이터 분석에 관련된 기술을 포스팅하고 싶었지만, 데이터 분석은 data specific한 부분들이 있기 때문에 일반적인 데이터 분석 및 시각화 기법에 대한 강의는 어려울것 같고, 뇌영상 데이터와 트위터 데이터 수집 및 분석과 관련된 포스팅을 연재하고자 합니다.

일단 뇌영상 데이터 분석 기법으로 강의를 시작하는 이유는 최근 5년 동안 제가 연구해온 분야로 expert까지는 아니어도 intermediate 이상의 실력은 된다고 생각하고 있기에, 지금까지 습득한 노하우를 관련 분야에 계신 분들께 나누고 싶은 생각이 들었습니다.

뇌영상 분석에 사용되는 툴은 여러가지가 있지만, 보통은 MATLAB 기반의 SPM8, linux 기반에서 작동하는 AFNI 또는 FSL 등이 가장 많이 이용되고 있습니다.어떤 소프트웨어가 가장 좋은가? 라는 질문의 대한 답은... 내가 사용하기 편한 소프트웨어. 가 아닐까? 생각됩니다. 우수한 프로그램은 고성능의 알고리즘으로 무장하여 계산속도를 극대화 하는 것도 중요하지만, 사용자가 얼마나 편하게 접근할 수 있는가?에도 많은 노력을 기울여야 한다고 생각합니다.

필자는 MATLAB이 사용하기 편하고, engineering 기반이 아닌 사람들과 소통하기에 (뇌연구는 심리학, 정신의학, 물리학, 통계학, 전자공학, 의공학 등 다양한 전공을 가진 연구자들이 있기 때문에 공동연구와 연구자들간의 소통이 중요함) 가장 적합한 프로그램이라 생각하고, MATLAB을 사용하기 시작했습니다. 앞으로 'Data Analysis (for neuroscientist)'라는 주제로 한글 인터넷 강좌를 연재하고, MATLAB 뿐만이 아니라 python 및 linux script에 대한 내용도 다룰 예정입니다. 뇌영상 데이터를 연구 재료로 사용하고 계신 연구자들 중에서, GUI 환경의 분석에서 벗어나고자 하시는 분들께 조금이라도 도움이 되었으면 좋겠네요^^ 오늘은 그 첫번째 강좌로 "Data loading and writing using SPM8 toolbox"에 대한 강의를 하고자 합니다.

SPM8은 프로그래밍을 잘 몰라도 사용할 수 있는 막강한 GUI환경을 제공합니다. 이 GUI를 이용하면 뇌영상 데이터(fMRI, EEG, PET 등)의 전처리를 수행할 수 있습니다. 물론 GUI를 사용하지 않고, MATLAB command line을 통해서 더욱 편리하게 전처리를 할 수도 있지만, 그러기 위해서는 프로그래밍에 대한 기초 지식이 있어야 해요. 하지만 겁먹을 필요는 없고요, 앞으로 하나하나 배워나가면 됩니다.

일단 MATLAB에서 SPM8의 툴발스를 이용하여 뇌영상 데이터를 불러들이고, 또 어떤 연산 결과를 새로운 이름의 영상으로 저장하고자 한다면,

(1) SPM8 toolbox를 다운로드 받아야 합니다.

(2) 예제로 사용할 뇌영상 데이터가 필요합니다. 데이터가 없다면 SPM 홈페이지에 있는 auditory fMRI data를 사용하실 수 있습니다. (MoAEpilot.zip)


이제 다운로드 받은 영상 데이터를 matrix 형태로 불러들이기 위해서는 MATLAB을 실행시키고, 다음과 같이 명령어를 순서대로 입력하면 됩니다.

>addpath /Users/skyeong/spm8; % spm8에서 제공하는 모든 함수를 어떠한 경로에서도 사용할 수 있도록 설정. >data_path = '/Users/skyeong/Downloads/MoAEpilot/fM00223' ; % fMRI 데이터 위치의 절대경로 >fns = spm_select('FPList',fullfile(data_path),'^fM.*\.img$'); % 파일 이름이 fM으로 시작하고, 확장자가 .img인 모든 파일을 선택. >vs = spm_vol(fns); % 뇌영상의 header 정보 불러오기. >IMG = spm_read_vols(vs); % 뇌영상 데이터를 matrix 형태로 불러오기.

vs 변수에는 뇌영상 데이터의 header 정보가 저장되어 있습니다. 다음과 같이 MATLAB command line에서  vs(1) 이라고 입력하면, 첫번째 뇌영상 볼륨의 정보를 볼 수 있어요. 

>vs(1) ans = fname: '/Users/skyeong/Downloads/MoAEpilot/fM00223/fM00223_004.img' dim: [64 64 64] mat: [4x4 double] pinfo: [3x1 double] dt: [4 1] n: [1 1] descrip: 'SPM compatible' private: [1x1 nifti]

여기서 fname은 첫번째 볼륨vs(1)이 위치한 full file path를 의미하고, dim은 뇌영상 데이터의 dimension정보, dt(=data type)는 뇌영상 데이터의 저장 형태입니다. 보통 프로그래밍 언어에서는 boolean, integer, float 에 따라서 데이터를 저장하는 용량이 다른데, [4 1]은 복셀 하나에 저장되는 숫자가 4 bytes로 표현된다는 의미이고, 보통 4 bytes 이면 양의 정수를 표현하기에 적합하다고 생각하면 됩니다. 만약 어떤 연산의 결과가 소수점을 동반한다면 vs(1).dt=[16 1]로 설정해야 하고, 이렇게 하면 한 복셀당 16 bytes의 용량이 필요하기 때문에, 4 bytes로 저장될때보다 뇌영상 데이터의 용량이 4배로 늘어나게 되요. data type이  높다고 좋은것은 아니고, 계산결과가 소수형인지, 양의 정수형인지, 음의 정수를 포함하는지를 잘 판단하여 설정하는 것이 하드디스크의 용량을 적게 사용할 수 있는 노하우입니다. MATLAB의 Numeric Types에 대해서는 MathWorks의 홈페이지를 참고하면 자세히 알아볼 수 있어요.

이제 IMG 변수에 담긴 숫자들은 뭘 의미하는지 알아 볼까요? IMG변수에는 뇌의 활동에 따른 BOLD signal이 숫자의 형태로 각 볼셀에 저장되어 있습니다.

>size(IMG) ans = 64 64 64 96

MATLAB command line에 size(IMG)를 입력하면 IMG 변수가 4차원 형태로 되어 있음을 알 수 있다. 처음 3개 숫자는 x, y, z 축의 복셀 숫자를 의미하고, 네번째 숫자인 96은 시간축 정보를 의미합니다. 즉, 실험을 통해서 96개의 volumes을 획득한 것이고, 만약 repetition time (TR)이 2초 였다면, 96x2 sec = 192 sec 동안 fMRI 영상을 획득한 셈이겠죠? 

이제 첫번째 볼륨vs(1)의 intensity 값의 분표를 MATLAB의 hist() 함수를 이용하여 확인해 볼께요.

>figure; >data = IMG(:,:,:,1); % 첫번째 volume의 intensity 정보를 data라는 변수에 저장. >hist(data(:)); % 모든 복셀의 intensity 값의 분포를 확인. >figure; >hist(data(:),100); % 모든 볼셀의 intensity 값의 100개의 bins으로 나눠서 분포를 확인.


강좌를 올리는게 쉽지는 않네요, 몇줄 안되는 코드이지만 프로그래밍은 직접 실습해보는게 중요합니다. 관심 있으신 분들은, 꼭 집접 확인해 보시길. 다음 강좌에서는 MATLAB을 이용한 regression analysis, bandpass filtering, network analysis 등을 소개할 예정입니다. 질문은 다른 분들도 함께 공유할 수 있도록 블로그나 패이스북의 덧글로 부탁드립니다.

댓글
  • 프로필사진 김애령 선생님~~ SPM 보다가 여기까지 왔네요 ㅋㅋ 2014.04.17 10:08
  • 프로필사진 경성현 아... 별거 없는데... 뭔가 더 정리해야 하는데, 요즘 정신이 없어서 못하고 있네요..ㅠㅠ 2014.04.24 14:17 신고
  • 프로필사진 김태윤 안녕하세요! 여쭤보고 싶은게 있는데, SPM이 MAC버전은 없는건가요? 2015.07.09 17:26
  • 프로필사진 경성현 SPM은 매틀랩 툴박스이기 때문에 맥용 윈도우용 따로 없습니다. 2015.07.09 17:56 신고
  • 프로필사진 김태윤 아! 감사합니다 2015.07.09 17:59
  • 프로필사진 김태윤 >IMG = spm_read_vols(vs); % 뇌영상 데이터를 matrix 형태로 불러오기.
    이 부분에서,

    인덱스가 행렬의 차원을 초과합니다.

    오류 발생: spm_read_vols (line 31)
    Y = zeros([V(1).dim(1:3),n]); %-image
    data matrix

    이런 경우는 어떻게 해결해야되나요?
    2015.07.18 14:03
  • 프로필사진 경성현 vs=spm_read_vols('a.nii') 를 하고 나서, 매틀랩에서 vs라고 입력하면 뭐라고 나오나요? 2015.07.18 14:15 신고
  • 프로필사진 김태윤 >> vs = spm_read_vols('a.nii')
    비구조체형 배열의 필드를 참조하려고 했습니다.

    오류 발생: spm_check_orientations (line 24)
    dims = cat(1,V.dim);

    오류 발생: spm_read_vols (line 26)
    spm_check_orientations(V);

    >> vs

    vs =

    0x0 struct array with fields:

    fname
    dim
    dt
    pinfo
    mat
    n
    descrip
    private

    이렇게 떴습니다!
    2015.07.18 23:10
  • 프로필사진 경성현 여기서 일단은 a.nii 대신 실제로 존재하는 파일 이름을 직접 입력하셔야 하는데요.. 2015.07.19 11:15 신고
  • 프로필사진 김태윤 실제로 존재하는 파일 이름을 직접 입력해봐도 같은 결과가 나옵니다 ㅠㅠ 어떻게 하면 좋을까요..? 2015.07.20 21:19
  • 프로필사진 경성현 해당 파일이 존재하고, 경로명도 정확하게 입력해 주셨다면 오류가 발생하는 일은 없을것 같은데요. spm8이나 spm12를 Matlab에서 Set path 하신거는 맞죠? 그래도 잘 안된다면 주변에 잘 아시는 분들께 도움을 요청하시는게 좋을것 같습니다. 매틀랩 기초를 공부해 보시는 것도 도움이 될것 같습니다. 2015.07.21 00:04 신고
댓글쓰기 폼