顕微鏡で撮影した画像ファイル(Tiffファイルなど)を読み込んで
MATLABで数値行列として格納する
1.ファイルのフォーマットを確認する
例えばZDC顕微鏡を使ってMetamorphで撮影したとき、
画像ファイルの名前は以下のようになる。(設定条件によって多少変わる)
<ユーザーが記入した名前>_w<Wavelength番号><Wavelength名>_s<Position番号>_t<Timepoint番号>.TIF
同じフォルダに
<ユーザーが記入した名前>_thumb_~
という名前のファイルがあるが、これらは解析には使わない。
Wavelengthの数 * Positionの数 * Timepointの数 だけファイルが存在する。
複数のZ座標について撮影している画像はZの数だけ画像がある。
各ファイル名を手動で指定すると手間がかかりすぎるので、
for文などを用いてファイル名を指定していく
イメージング環境によってファイルの様式が異なるので逐一確認すること。
2.イメージング環境設定について、ファイルを読み込む。
Metamorphで撮影すると.nd という拡張子のファイルが作られる。
これの実態はテキストファイルで、MATLABで読み込める。
ndファイルには、撮影時に実験者が書いたDescriptionや、
各種設定事項が記述されている。
ここからTimepointの数、Wavelengthの数とそれぞれの名前、Positionの数
といった情報を取得できる。
サンプルコード。ndファイルの読み込み
% ------------------------------------------------------------------------
% イメージング情報が記述されたndファイルを読み込んでimaging_info構造体に格納
% ndファイルを読み込んで文字列リストとして格納
fid = fopen([directory, '\', filename, '.nd']);
cellarray = textscan(fid, '%s', 'delimiter', ','); % セル配列が返る
nd = cellarray{1}; % 行列に格納
fclose(fid);
% 読み込んだ文字列リストからimaging_info構造体に格納
for i = 1 : length(nd)
if strcmp(nd(i), '"StartTime1"') % start day and time (秒単位 seconds)
date = nd{i + 1}; % nd(i + 1)とするとセル配列が入る
imaging_info.start_time = datenum(date,'yyyymmdd HH:MM:SS') * 86400; % 文字列から秒単位の数値に変換
elseif strcmp(nd(i), '"DoTimelapse"') % Timelapse on or off
imaging_info.do_timelapse = nd{i + 1};
elseif strcmp(nd(i), '"NTimePoints"') % number of timepoints
imaging_info.timepoints = str2double(nd(i + 1));
elseif strcmp(nd(i), '"NStagePositions"') % number of positions
imaging_info.positions = str2double(nd(i + 1));
elseif strcmp(nd(i), '"NWavelengths"') % number of wavelengths
imaging_info.wavelengths = str2double(nd(i + 1));
elseif strcmp(nd{i}(2:length(nd{i}) -2) , 'WaveName') % 「" "」と数字を除く("WaveName1" → WaveName)
num = str2double(nd{i}(length(nd{i}) -1)); % nd(i)とすると文字列ではなくセル配列が返る
imaging_info.wavename{num} = nd{i + 1}(2:length(nd{i + 1}) -1); % wavenameはセル配列
end
end
% ------------------------------------------------------------------------
このような環境設定のファイルが用意されていないイメージング環境の場合は、
手動でこれらの情報をコードに記述するか、
以下のように情報を取得することになる。
サンプルコード。フォルダの数を調べる
% ------------------------------------------------------------------------
% フォルダの数を調べる
% フォルダ名がa_01.oif.filesから始まって2ずつ増える
file_temp=sprintf('%s/files/a_01.oif.files',directory);
is_exist=exist(file_temp, 'file');
i=1;
while is_exist ~=0
i=i+1;
t_temp = 1+i*2;
if t_temp<100
file_temp=sprintf('%s/files/a_%02d.oif.files',directory,t_temp);
else
file_temp=sprintf('%s/files/a_%03d.oif.files',directory,t_temp);
end
is_exist=exist(file_temp, 'file');
end
folderindex = 1 : 2 : t_temp-2;
% ------------------------------------------------------------------------
これはある二光子顕微鏡で撮影した画像について、Timepointの数を調べる例。
1フォルダに1Timepointのデータが入っている。
Timepointがいくつあるのかを記述したファイルなどがないため、
ある番号のフォルダが存在するかどうかを調べて、
存在するフォルダの数をカウントしている。
3.パスを指定して読み込む
サンプルコード。ZDC顕微鏡を使ってMetamorphで撮影したとき
%-------------------------------------------------------------------------------
for i = 1 : wavelengths
for j = 1 : positions
for k = 1 : timepoints
% Tiffファイルのパスを設定
if strcmp(do_timelapse, 'FALSE')
path = [directory, '\', filename, '_w', int2str(i), wavename{i}, '_s', int2str(j), '.TIF'];
else
path = [directory, '\', filename, '_w', int2str(i), wavename{i}, '_s', int2str(j), '_t', int2str(k), '.TIF'];
end
% Tiffオブジェクト(読み込みモード)として読み込み
tiff_temp = Tiff(path, 'r');
% readで画像を読み込み
Image_array{i,j,k} = read(tiff_temp);
% 撮影時刻を読み込み
DateTime = tiff_temp.getTag('DateTime');
% 文字列から秒単位の数値に変換
Time_array(i,j,k) = datenum(DateTime, 'yyyy:mm:dd HH:MM:SS') * 86400;
end
end
end
%-------------------------------------------------------------------------------
この例の場合、Timelapseをするかどうかでファイル名のつけ方が変わるので
場合分けをしている。
ファイルを読み込むには、そのファイル形式に対応した関数を使う。
imread関数が多くのファイル形式に対応している。
Tiffファイルを読み込むためのものとしてTiffクラスがあり、
Tiffクラス内に各種関数が用意されている。
Tiffファイルには画像情報だけではなく、タグとして文字列情報も含まれている。
また、1つのファイル内に複数の画像を含めることもできる。
全ての情報がまとめて入っているのがTiff関数の返り値となるTiffオブジェクトで、
そこからread関数で画像情報を取得したり、
getTag関数でタグ情報を取得したりする。
読み込んだ画像情報は、モノクロなら2次元配列、カラーなら3次元配列になる。
これがwavelength, position, timepointの分だけある。
これらを格納するには、多次元行列にするかセル配列を使うことになる。
状況に応じて使い分ける。
読み込んだ画像のデータ型には注意すること。
uint8なのかuint16なのかdoubleなのか
常にデータ型を意識してプログラムを書かないと、
エラーが起きたり、思わぬ動作をしたりする。
例えば、整数型として格納された画像にたいして数値演算をすると
小数値をとることができないためバグのもとになる。