画像内の余分なところを除いて新しい行列にしたい

12 views (last 30 days)
thuru
thuru on 19 Jan 2017
Commented: thuru on 26 Jan 2017
添付してある画像のように、解析に用いたい部分が中央にあるのですが、そのまま使うと余計な数値が入ってしまい困っています。 添付画像は256×256 uint16です。周りのグレーの行列の値は32768です。32768の部分が邪魔になっています。トリミングみたいに、余計な部分を省いて新しい行列を作成したいです。
  3 Comments
thuru
thuru on 20 Jan 2017
取り出したい位置が分からなく、できれば自動で決定したかったのですが、調べてもわからなかったので、自分で行列の要素を見て手動で位置を決定しました。 回答者様の関数で実行できそうです。ありがとうございました。
thuru
thuru on 20 Jan 2017
度々失礼します。実行したところエラーが起きてしまいました。 fileFolder = fullfile(pwd,'Series1'); % 画像の読込み (67枚の断面画像)
tifFiles = dir(fullfile(fileFolder,'*.tif'));
numfiles = length(tifFiles);
img = imread(tifFiles(1).name);
img2 = img(58:124, 110:176);
grayscale = zeros(size(img2,1),size(img2,2),numfiles);
for k = 2:numfiles
grayscale(:,:,k) = imread(tifFiles(k).name);
end
axis vis3d equal;
今まではimg2の行を書いていなかったためgrayscaleは256×256だったのですがimg2を入れた後は67×67です。 しかしfor文のところで
添字による代入の次元が一致しません。
というエラーが出ます。原因が分かりません。

Sign in to comment.

Accepted Answer

Takuji Fukumoto
Takuji Fukumoto on 24 Jan 2017
画像の周囲と中央の境界になっている部分を検出してトリミングするサンプルです。
I = imread('grayscale2.png');
Ig = rgb2gray(I);
Ie = edge(Ig,'Sobel',0.00001);
Ie(end-3:end,:)= 0;
[row,col] = find(Ie);
rmax = max(row);rmin = min(row);cmax = max(col);cmin = min(col);
I2 = I(rmin:rmax,cmin:cmax,:);
figure,imshow(I2)
画像のトリミングでは直交する行列方向での切り出しになります。 領域周囲の直線が斜めになっているところは残ってしまいます。
領域の解析だけもう少し厳密にするのであれば、
h = impoly(gca, [188,30; 189,142; 93,141; 13,41]);
BW = createMask(h);
I(~BW) =0;
によってマスク以外のところはゼロにすることができるので、 Ieの頂点座標を使うか、マウス操作でimpolyの頂点を動かして領域を決定して用いることが出来ます。
  3 Comments
Takuji Fukumoto
Takuji Fukumoto on 25 Jan 2017
Edited: Takuji Fukumoto on 25 Jan 2017
各処理後の領域の最大最小をあらかじめ求めてから、全部同じ座標で切り出すのではいかがでしょうか。
for n=1:67
In = imread('Filename');
Ig = rgb2gray(In);
Ie = edge(Ig,'Sobel',0.00001);
Ie(end-3:end,:)= 0;
[row,col] = find(Ie);
rmax(n) = max(row);rmin(n) = min(row);cmax(n) = max(col);cmin(n) = min(col);
end
rmaxall = max(rmax);
rminall = min(rmin);
cmaxall = max(cmax);
cminall = min(cmin);
for k=1:67
In = ('Filename');
Inout = In(rminall:rmaxall,cminall:cmaxall,:);
end
画像の読み出しと出力のところは編集してご利用ください。
thuru
thuru on 26 Jan 2017
ありがとうございます。使ってみます。

Sign in to comment.

More Answers (2)

michio
michio on 23 Jan 2017
上記の「添字による代入の次元が一致しません。」というエラーですが、
grayscale(:,:,k) = imread(tifFiles(k).name);
の実行において grayscale は 67×67×numfiles の配列ですが、imread で読み取られる画像サイズが 256×256 となっており、配列のサイズが合致していないことが原因です。
for k = 2:numfiles
img = imread(tifFiles(k).name);
grayscale(:,:,k) = img(58:124, 110:176);
end
と配列のサイズを合わせて grayscale に代入してやってください。
また、もし余分なところを取り除いた後に残る中心部分の画像のサイズが事前に分かっていれば、下記の方法が使えるかなと。
5x5の2次元配列から、100である部分を除いて3x2の配列を取り出しているサンプルになります。
% サンプルデータ(周囲が値100で囲まれた 3x2 の画像)
imag1 = 100*ones(5,5);
imag1(2:4,2:3) = rand(3,2)
copy = imag1;
% 100の値を持つ要素を削除
% 中心部分のデータが抽出できますが、すべての要素が
% 一列に並んだベクトルとして(ここでは 1x6 のベクトル)でてきます。
copy(copy==100) = [];
% 一列に並んだデータを2次元に並べ替え (ここで、事前に中心部分の画像サイズが必要)
imag2 = reshape(copy,3,2)

michio
michio on 23 Jan 2017
Edited: michio on 23 Jan 2017
すべての要素が1の列(または行)を見つけ出す all関数 を使った方法を紹介します。
下記を実行して、変数 row clm などの値を確認してみてください。
また、
copy(:,row) = []; % 要素がすべて1の行を削除
など、= [] で対応する要素を削除することができることを利用します。
% サンプルデータ(周囲が値100で囲まれた 3x2 の画像)
imag1 = 100*ones(5,5);
imag1(2:4,2:3) = rand(3,2)
copy = imag1;
% 100の値を持つ要素位置に1をもった論理配列を作成
idx = copy == 100
row = all(idx,1); % 要素が全て1の行を検出
clm = all(idx,2); % 要素が全て1の列を検出
copy(:,row) = []; % 要素がすべて1の行を削除
copy(clm, :) = [];% 要素がすべて1の列を削除
copy
  1 Comment
thuru
thuru on 23 Jan 2017
ありがとうございます。試してみます。

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!