MATLAB 영상처리 기초 - 화질향상 및 공간필터링

[MATLAB 영상처리 기초 1] stack image, image-set 불러오기 (part2) - imread( ), z-projection, imageDatastore( )

toyprojects 2023. 12. 7. 18:23

 

 

 

 

Stack image, image-set 불러오기 소개 동영상

 

 

Stack image 불러오기 

 

인간의 뇌를 MRI(자기공명영상장치) 로 촬영한 영상 (출처 1)

 

 

 

위의 이미지는 인간의 뇌를 MRI(자기공명영상장치)로 촬영한 영상입니다.

( 위 이미지는 본 블로그 맨밑 출처 1에 가셔서 다운로드 받을 수 있습니다.)

인간의 뇌를 수평방향 섹션으로 layer별로 imaging 한것을 하나의 이미지 파일로 담았고,

이것을 stack image 이라고 합니다.

따라서 하나의 stack image에는 여러개의 layer 또는 frame 이미지를 저장하고 있습니다.

 

대상 이미지의 세부정보, 예를들어 layer의 수, 이미지의 너비, 높이 등을 알기위해 imfinfo( )

명령어를 사용하였고, 모든 layer 데이터를 하나의 변수에 저장하기 위해 imgSet 변수를

생성하였습니다. 

각 layer 이미지는 2차원의 데이터로써 imgSet 변수는 (이미지의 높이, 너비, layer 수) 순서의

3차원 구조를 갖습니다.

 

그리고 imread( ) 명령어를 이용해 하나의 layer 씩 이미지를 불러와 imgSet 변수에 저장

하였습니다. 이때 for-loop를 통해 입력 이미지의 각 layer를 순대로 indexing 하였습니다.

 

% image ref.: http://imagej.nih.gov/ij/images/mri-stack.zip
file_name = "mri-stack.tif";
info = imfinfo(file_name); 

num_frame = numel(info);
img_width = info.Width;      
img_height = info.Height;

imgSet = zeros(img_height,img_width,num_frame);     % make an empty data-set
% read a stack image layer by layer, or frame by frame 
for f_iter = 1:1:num_frame
    imgSet(:, :, f_iter) = imread(file_name,f_iter);
end

 

 

다음은 stack image를 출력하는 코드로써 모든 layer를 1초 간격으로 보여줍니다.

각 layer 이미지의 높이, 너비는 각각 226, 186 pixel 로써, 이미지를 조금 확대하여

출력하기위해 imshow( ) 함수에 'InitialMagnification' 옵션을 'fit' 으로 지정하였습니다.

 

% show all layers(or frames) of the stack image every 1sec
figure;
for f_iter = 1:1:num_frame
     imshow(imgSet(:,:,f_iter),[ ], 'InitialMagnification', 'fit')
     pause(1)
end

 

 

 

Medical 또는 microscope imaging 분야에서 (위의 MRI 이미지 같이) z축 방향으로 

- 이미지의 너비, 높이를 각각 x, y 방향이라 가정한다면 z방향은 이미지의 깊이 - 

2차원 이미지를 켜켜이 겹쳐놓은것을 z-stack image 이라고 합니다. 

( 위의 MRI 이미지 또한 z-stack image 이라고 할 수 있습니다. )

 

이미지 프로세싱/분석의 목적에 따라 z-stack image의 구조적, 기능적 특징을 검출하는 

다양한 테크닉이 활용됩니다. 간단한 예로써, MRI 영상의 전체 layer 이미지 픽셀값의 평균을

이용한 average intensity z-projection, 픽셀의 최대, 최소값을 이용한 maximum/minimum

intensity z-projection 을 다음과 같이 보여 줍니다.

 

Average intensity z-projection의 경우, 각 layer의 이미지들을 더한(= 선형 합) 다음

layer의 수만큼 나누어 픽셀값 평균을 구하였습니다.

 

 

 

 

 

% average intensity z-projection
img_sum = zeros(img_height,img_width);
for f_iter = 1:1:num_frame
     img_sum = img_sum + imgSet(:,:,f_iter);
end
img_mean_stack = img_sum / num_frame;

% max intensity z-projection
img_maxP = max(imgSet, [], 3);

% min intensity z-projection
img_minP = min(imgSet, [], 3);

figure; 
subplot(1,3,1); imshow(img_mean_stack,[ ], 'InitialMagnification', 'fit');  title('\fontsize{20}Average Intensity Z-Projection');
subplot(1,3,2); imshow(img_maxP,[ ], 'InitialMagnification', 'fit'); title('\fontsize{20}Maximum Intensity Z-Projection');
subplot(1,3,3); imshow(img_minP,[ ], 'InitialMagnification', 'fit');  title('\fontsize{20}Minimum Intensity Z-Projection');

 

 

 

 

Image-set 불러오기 

 

대량의 이미지 파일 모음을 image-set 이라 하고, 주로 시간에 따라 연속적으로 imaging 된

이미지 파일 모음의 경우가 많습니다. 

다음과 같은 경우, 하나의 폴더에 총 122개의 이미지 파일이 있으며, 이것들은 microscope의

0과 1번 채널이 각각 시간에 따라 imaging이 된 결과를 보여줍니다. 이미지 파일이름 끝부분에

'ch00', 'ch01'은 각각 microscope의 채널 번호를 뜻하고, 'z00', 'z01', .... , 'z#' 은 시간에 따른 

imaging 순서를 뜻합니다.  

( image-set은 본 블로그 맨밑 출처 2에 가셔서 다운로드 받을 수 있습니다.)

 

 

 

하나의 폴더에 위치한 imge-set

 

 

 

만일 이미지 프로세싱을 위해 모든 이미지 데이터(image-set)를 MATLAB의 workspace에

불러온다면 대상 이미지 데이터 만큼의 memory 용량이 필요하고, 작업 수행에 따라 추가적인

memory 용량이 요구됩니다. 따라서, 물리적인 memory 용량을 넘어서는 이미지 데이터 또는

image-set의 이미지 프로세싱을 위해 특별한 기능이 요구됩니다.

 

imageDatastore( ) object는 규모가 큰 image-set 을 한꺼번에 workspace에 load 하지 않고 작업을 

수행할 수 있는 방법을 제공합니다. 이를 활용하기 위해, 우선 image-set이 위치한 폴더경로를 

입력 파라메터로 지정함으로써 새로운 datastore object를 생성합니다. 

 

생성된 object(= img_ds)의 속성을 통해 image-set의 경로+파일이름, 추가적으로 image-set의 크기

또한 알 수 있습니다. 이 object가 제공하는 함수를 이용해 image-set 전체 또는 특정 이미지를 

 load 할 수 있습니다. 

 

 

% image ref.: https://isg.nist.gov/deepzoomweb/fileBrowsing/3D/Raw_tiff/Microfibers
folder_name = "011714_SJF_BigNF_1d_63x_07";
img_ds = imageDatastore(folder_name);
img_fileName = img_ds.Files;
num_file = numel(img_fileName);

img = readimage(img_ds,1);       % read the 1st image
imgSet = readall(img_ds);        % read all image in datastore

 

 

만일 microscope의 1번 채널의 이미지 파일 모음만을 불러오기 원한다면 imageDatastore( ) object

생성시 파일명 조건식을 함께 지정해 줄 수 있습니다. 이미지 파일이름 끝부분에 'ch01'은 1번 채널

이미지 데이터를 뜻하므로  「 folder_name + " /*_ch01.tif " 」 를 imageDatastore( ) object의 입력

파라메터로 지정합니다.

 

새로 생성된 datastore object(= img_ds_ch01)의 Files 속성에서 보듯이, 오직 1번 채널의 image-set만이

workspace에 load 되었습니다. 

 

 

% read all images which are channel1 images
target_fileset = folder_name + " /*_ch01.tif ";
img_ds_ch01 = imageDatastore(target_fileset);
imgSet_ch01 = readall(img_ds_ch01);

 

 

 

 

 

 

다음 workspace에 load 된 1번 채널 image-set의 영상을 0.2초 단위로 출력합니다.

 

 

ch01 image-set의 출력 (출처 2)

 

 

% show all images every 0.2sec 
figure;
for f_iter = 1:1:numel(img_ds_ch01.Files)
     imshow(imgSet_ch01{f_iter},[ ], 'InitialMagnification', 'fit')
     pause(0.2)
end

 

 

 

 

마지막으로 본 글에 쓰인 모든 MATLAB 코드는 밑에 표시해 두었습니다.

 

% read image-set using imageDatastore

% image ref.: https://isg.nist.gov/deepzoomweb/fileBrowsing/3D/Raw_tiff/Microfibers
folder_name = "011714_SJF_BigNF_1d_63x_07";
img_ds = imageDatastore(folder_name);
img_fileName = img_ds.Files;
num_file = numel(img_fileName);

img = readimage(img_ds,1);       % read the 1st image
imgSet = readall(img_ds);        % read all image in datastore

% read all images which are channel1 images
target_fileset = folder_name + " /*_ch01.tif ";
img_ds_ch01 = imageDatastore(target_fileset);
imgSet_ch01 = readall(img_ds_ch01);

% show all images every 0.2sec 
figure;
for f_iter = 1:1:numel(img_ds_ch01.Files)
     imshow(imgSet_ch01{f_iter},[ ], 'InitialMagnification', 'fit')
     pause(0.2)
end

 

 

 

출처1: http://imagej.nih.gov/ij/images

 

Index of /ij/images

 

imagej.net

 

 

 

출처2: https://isg.nist.gov/deepzoomweb/fileBrowsing/3D/Raw_tiff/Microfibers

 

NIST Computational Science in Metrology

 

isg.nist.gov