三次元行列をslic​e関数でイメージ表示​させたのですが、中を​透過させたいです。

添付画像のように三次元行列をslice関数でイメージ表示させたのですが、強度が上面しか見えなくて、中の強度が知りたいのですが透過させる方法が分かりません。AlphaDataを使用するコードが分かりません。下記のコードで作成しました。 67×67×67 uint8の画像です。
fileFolder = fullfile(pwd,'Series1'); % 画像の読込み (67枚の断面画像)
tifFiles = dir(fullfile(fileFolder,'*.tif'));
numfiles = length(tifFiles);
for k = 1:numfiles
eval(strcat('img', num2str(k),'= imread(tifFiles(k).name)'));
eval(strcat('a = img', num2str(k),';'));
eval(strcat('imgR', num2str(k),'= a(58:124, 110:176)'));
eval(strcat('b = imgR', num2str(k),';'));
eval(strcat('imgE', num2str(k), '=im2uint8(b)'));
end
for k = 1:numfiles
eval(strcat('a = imgE', num2str(k),';'));
grayscale(:,:,k) = a;
end
h = slice(double(grayscale),[1,67],[1,67],[1,67]);
h(1).EdgeColor = 'none';
h(2).EdgeColor = 'none';
h(3).EdgeColor = 'none';
h(4).EdgeColor = 'none';
h(5).EdgeColor = 'none';
h(6).EdgeColor = 'none';

 採用された回答

michio
michio 2017 年 1 月 26 日

4 投票

おそらく描画されたいのは下記で表示されるような3D表示でしょうか。
slice 関数では特定の面だけを描画していますので、そのまま AlphaData の値を操作して透過させても内部には何もありません。ですので、例えば各軸方向に100毎のスライス表示を行い、それぞれを半透明表示にすることで、内部の分布状態も見ることができるような表示にすることができるかもしれません。
冒頭のリンク先の3D描画にはこちらの関数( File Exchange: pcolor3) を使用していますが、まさに前述の複数のスライス画像を重ねて半透明表示にするという操作をやっています。ただ、R2014b 以降のバージョンでは正しく動かないとの記載も見られますが参考まで。

21 件のコメント

thuru
thuru 2017 年 1 月 26 日
回答ありがとうございます。 まさに上記のリンク先のような表示ができたらいいなと考えています!pcolorというのは三次元行列の場合使えるのでしょうか?またリンク先の下の方にも三次元表示されているのがありますが、あれはどうやって実現できるのでしょうか?
sliceに関して、各軸ごとに100枚のスライスとはどういう意味でしょうか。
michio
michio 2017 年 1 月 27 日
pcolor3 関数はユーザー作成の関数で3次元も対応してそうですよ。リンク先を確認してみてください。
100枚のスライスというのは、複数のスライス画像の重ね方の一例ですが、3次元のボリュームデータを表示する面(スライス)を(例えばそれぞれの軸に垂直に)100箇所に設置し、それぞれを半透明にすることで pcolor3 の様な挙動を実現します。
下の例は、データを表示する面(スライス)を斜めに設置し、内部の様子を表示しています。 http://jp.mathworks.com/help/matlab/visualize/exploring-volumes-with-slice-planes.html
thuru
thuru 2017 年 1 月 27 日
pcolor関数、なかなか実現できなくて難しいですが頑張ってみます。
理解できました!早速やってみます。
michio
michio 2017 年 1 月 27 日
MATLAB の pcolor関数ではなく、File Exchangeに公開されいてるユーザー作成の pcolor3 関数ですので、お気をつけください。
thuru
thuru 2017 年 1 月 27 日
すみません誤字でした、pcolor3頑張ります。
michio
michio 2017 年 1 月 27 日
Good luck :)
thuru
thuru 2017 年 1 月 28 日
pcolor3(grayscale);とやると下記のようなエラーが出てしまいました。grayscaleをdoubleに変えてもやはりエラーが出てしまいます。。 下記のエラーは何を意味しているのでしょうか?
エラー: griddedInterpolant サンプル値は、single または double の配列でなければなりません。
エラー: interp3 (line 142) F = griddedInterpolant(X, Y, Z, V, method,extrap);
エラー: slice (line 104) vi = interp3(x,y,z,v,xi,yi,zi,method);
エラー: pcolor3 (line 249) h = slice(X,Y,Z,V,xslice,yslice,zslice,InterpolationMethod);
michio
michio 2017 年 1 月 28 日
せっかくですのでMATLABのデバック機能を使って、原因の追究に挑戦してみてください。
上記ページに詳細がありますが、まずは pcolor3 の 249行目にブレークポイントを設定し、slice関数への入力引数がちゃんと double 型になっているかどうかの確認からですね。
thuru
thuru 2017 年 1 月 29 日
エラーをみてdouble型にしたのですが、
警告: Surface の作成中または更新中のエラー プロパティ FaceAlpha の値のエラー FaceColor が 'interp' の場合、FaceAlpha は 'interp' または 0 と 1 の間の数値でなければなりません。
という警告が出てきて、FaceColorをinterpにしていませんし、何がいけないのかさっぱりです。。
リンク先では、pcolor3を適用しているのはx,yなどの関数ですが、三次元行列をpcolor3で三次元表現できるのかわかりません。
michio
michio 2017 年 1 月 30 日
interp の設定は pcolor3 関数内で実行しているようですよ。
以前も記載いたしましたが、まず pcolor3 関数は製品の一部の関数ではなく、ユーザーの Chadさんが独自に書かれた関数です。 そして、残念ながら pcolor3 by Chad Greene の冒頭にあるように "Note: This function does not yet work for Matlab 2014b or later." ということで、 製作者自身がR2014b以降のバージョンでは正常に動かないと記載しています。 ですので、R2014b 以降のバージョンを使っている場合には、意図通りに動かない可能性があります。
この関数を使用する限りは、 R2014a 以前のバージョンを使用するか、 R2014b 以降のバージョンでも機能するように独自に改変を加えるかの2択になります。
関数の中身を読んで描画手法を盗んで thuruさんが独自に描画関数を作成するか、 R2014b 以降のバージョンでも動くよう 改善を加えるのもよい練習になるかと思いますが、お急ぎの場合にはあまり pcolor3 の使用にこだわるのはおすすめできません。
michio
michio 2017 年 1 月 30 日
編集済み: michio 2017 年 1 月 30 日
上記のことをご了承頂いた上で、それでももし pcolor3 関数をベースにプログラムを進められるのであれば、製作者が用意しているヘルプページ(英語ではありますが・・)は少なくとも読んで理解してください。
基本的には Yoshio さん、Takujiさんがおすすめしている方法と同じで、データの様子を表示するスライス面を選択し、データを表示しています。
参考まで、乗りかかった船ですのですこし変更を加えた pcolor3_MI 関数を添付しました。
[x,y,z] = meshgrid(-2:.1:2,-2:.1:2,-2:.1:2);
v = x.*exp(-x.^2-y.^2-z.^2) + 1;
pcolor3_MI(v,'N',3,'alphalim',[1 1.1])
axis tight
'N' の後に続く数値が、各軸何枚のスライスを表示するかを指定しますが、あまり大きくするとキレイに表示できませんので、3程度にしておいてください。'alphalim' オプションに関しては、上記のヘルプページに説明があります。
thuru
thuru 2017 年 1 月 30 日
ご丁寧な説明ありがとうございます。MATLABに関する理解不足で迷惑をおかけしまして申し訳ありません。。
時間がないので別の方法を考えた方がいいのでしょうが、時間がないことによって勉強の方も疎かになっている状況ですので、なんとかpcolor3で表示さえできればいいと考えております。
上記のコードで、やはりvがx,y,zの関数になっていますね。行列には対応できないのでしょうか。行列はx,yなど用いた関数表現できないですし、、
michio
michio 2017 年 1 月 30 日
編集済み: michio 2017 年 1 月 30 日
[x,y,z] = meshgrid(-2:.1:2,-2:.1:2,-2:.1:2);
v = x.*exp(-x.^2-y.^2-z.^2) + 1;
を実行して頂けますと、x,y,z,v それぞれが3次元配列になっていることが確認できると思いますので、見てみてください。
それから、
opengl software
と実行した後に上記の pcolor3_MIを使った場合、'N' = 3 を大きな数値にしてもそれらしく表示されますので、とりあえずの解決策としてはよいかもしれません。描画速度が若干遅くなりますので、気をつけてください。詳細 OpenGL レンダリングの制御
もとの設定に戻す場合は
opengl hardware
と実行してください。
michio
michio 2017 年 1 月 30 日
編集済み: michio 2017 年 1 月 30 日
最後になりますが、MATLABの基本的な操作方法やエラーの解釈方法など、2 時間程度で受けられるオンライン MATLAB 入門(無料)お勧めですよ。2時間で今後の効率が大分変わると思います。無料ですので是非。 https://matlabacademy.mathworks.com/jp
時間がないときこそ急がば回れで、闇雲にトライするより効率がよいと思います。
thuru
thuru 2017 年 1 月 30 日
meshgridについて勘違いしてました。確かに三次元配列になっていました。 grayscaleをdoubleにして実行するとエラーはなくなりましたが添付画像のようになり、三次元配列がうまく重なりませんでした。グリッド領域などが関係しているのでしょうか。
michio
michio 2017 年 1 月 30 日
編集済み: michio 2017 年 1 月 30 日
申し訳ありませんが想像力に限界もあり、流石にこれだけでは何もコメントできません。
短時間で解決策を得たい気持ちはわかりますが、どんなコマンドをどんなデータに実行したのか、何を期待して実行した結果なのか、期待した結果と異なる点は何か。できれば解決するためにご自身で何をトライしたのかなど、記載して頂けますでしょうか。
thuru
thuru 2017 年 1 月 30 日
失礼しました。
fileFolder = fullfile(pwd,'Series1'); % 画像の読込み (67枚の断面画像)
tifFiles = dir(fullfile(fileFolder,'*.tif'));
numfiles = length(tifFiles);
上記のコードでtifファイルを読み込みました。このtifファイルはもともと100×100の画像データで、配列に規則性はありません
for k = 1:numfiles
eval(strcat('img', num2str(k),'= imread(tifFiles(k).name)'));
eval(strcat('a = img', num2str(k),';'));
eval(strcat('imgR', num2str(k),'= a(58:124, 110:176)'));
eval(strcat('b = imgR', num2str(k),';'));
eval(strcat('imgE', num2str(k), '=im2uint8(b)'));
end
上記のループで、先ほどのtifファイル67枚を全て自分が解析に用いるために、トリミングして、67×67uint8のグレースケールの配列としました。
for k = 1:numfiles
eval(strcat('a = imgE', num2str(k),';'));
grayscale(:,:,k) = a;
end
先ほどの67枚の画像を一つの三次元配列にまとめました。
そこでこの三次元配列を、強度の違いによって差が分かるように可視化したいと考え、michio様の提案されたpcolor3関数が適切だと考え、この関数を使おうと考えました。
そこで uint8のgrayscaleをdoubleに変換し、とりあえずpcolor3関数を適用してみました。
grayscale = grayscale(double) pcolor3_MI(grayscale,'N',3,'alphalim',[1 1.1]) axis tight
すると先ほど送った画像のようになり、うまく表示できませんでした。 画像が重なってなく、直交してたりして、原因が分かりません。
michio
michio 2017 年 1 月 30 日
編集済み: michio 2017 年 1 月 30 日
詳細にまとめてくださりありがとうございます。 ただ、コードと実行結果を拝見する限り、コードの意図通りに表示されている様に見受けられます。
繰り返しになりますが、pcolor3 関数は各軸に直行する面を選び( N = 3 であれば3枚)、それぞれの面(スライス面)上に3次元データを表示する処理を行っています。各面に透明性を持たせることにより、3次元データを描画しています。ですので、thuruさんの実行結果も画像が直行しているように見えています。
grayscale = grayscale(double);
pcolor3_MI(grayscale,'N',3,'alphalim',[1 1.1])
axis tight
'N' の右の数値(上記では 3) を大きな数値したり、'alphalim' の右にある値 [1 1.1] を変更することで見栄えが変わりますのでデータに合わせて試行錯誤してみてください。
特に 'alphalim' オプションの使い方は下記URLの Example 2: Adjusting appearance を確認してみてください。例題にある通り、'alphalim' はデータ内のどの数値に注目するかを指定できます。
'N' の値を大きくする場合は、前のコメントで既にご紹介したものですが、
opengl software
grayscale = grayscale(double);
pcolor3_MI(grayscale,'N',10,'alphalim',[1 1.1])
axis tight
と opengl software を加えると R2014b 以降のバージョンでもそれなりの描画ができるかもしれませんので試してみてください。
繰り返しになりますが、pcolor3 関数をベースにプログラムを進められるのであれば、製作者が用意している ヘルプページ (英語ではありますが・・)も読んでみてくださいね。
thuru
thuru 2017 年 1 月 31 日
ありがとうございます!'N'はそういう意味だったのですね。確かに挙動がおかしいですが、なんとか三次元表現できました。色がなぜか変えられないですが、今後頑張ってみます。 色々とありがとうございました!!
michio
michio 2017 年 1 月 31 日
色はおそらくカラーマップの変更が有効です。 下記キャプチャ画像の矢印部分で示される部分で他のカラーマップを選択してみてください。
thuru
thuru 2017 年 2 月 4 日
ありがとうございます! やはりNが67だとかなり重くなってしまいますね。。。

サインインしてコメントする。

その他の回答 (2 件)

Yoshio
Yoshio 2017 年 1 月 27 日

5 投票

簡単にお試しになるなら、これではどうでしょうか。
[x,y,z] = meshgrid(-2:.2:2,-2:.25:2,-2:.16:2);
v = x.*exp(-x.^2-y.^2-z.^2);
xslice = [.8,2];
yslice = 2;
zslice = [-2,0];
h = slice(x,y,z,v,xslice,yslice,zslice);
xlabel('X'),ylabel('Y'),zlabel('Z')
set(h,'EdgeColor','none','FaceColor','interp',...
'FaceAlpha','interp')
alpha color
alpha scaled
alpha関数に関するヘルプが https://jp.mathworks.com/help/matlab/ref/alpha.html にありますので、参考になさってください。
なお、ユーザ作成のpcolor3 関数に関しましては、こちら http://jp.mathworks.com/matlabcentral/fileexchange/49985-pcolor3/content/pcolor3/pcolor3.m からソースコードが見られますので、中身をご自身で解析するか、 http://jp.mathworks.com/matlabcentral/fileexchange/49985-pcolor3/content/pcolor3/html/pcolor3_documentation.html を介して質問する、直接作者にメールする等でご対応願います。

1 件のコメント

thuru
thuru 2017 年 1 月 27 日
ありがとうございます、上記のコードを自身のgrayscaleで試してみたのですが、側面しか表示されませんでした。。
pcolor3関数に関しまして、ありがとうございます!試してみます。

サインインしてコメントする。

Takuji Fukumoto
Takuji Fukumoto 2017 年 1 月 26 日

3 投票

1 件のコメント

thuru
thuru 2017 年 1 月 26 日
回答ありがとうございます。スライス離すことで中が見えそうですね、試してみます。

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeGraphics Performance についてさらに検索

質問済み:

2017 年 1 月 26 日

コメント済み:

2017 年 2 月 4 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by