4

さて、私の問題をタイトルで説明する方法がわかりません。私が得たものが正しいことを願っています。

Mこの場合、11x11x11のボクセルで構成された3D画像であるマトリックス(以下の例)があります(簡単にするために論理的にしました。サイズも単なる例です)。

私のコードでは、いくつかのボクセルの 26 個の近傍に到達する必要があります。そのために、http: //www.mathworks.com/matlabcentral/answers/86900-how-to-find-allにあるファンシーな線形インデックスを使用します。 -n次元行列の要素の隣人

問題は、が範囲外の値pointの「境界」にMある場合にアクセスしようとすると、エラーが発生することです。

この問題を解決するにはM、すべての次元で+2サイズになるように境界を作成し、それにゼロを入力することをM勧めしますが、私のコードは例。

私はそれを行う方法を見つけることができません。私はここで少し立ち往生しています。なにか提案を?

編集: @Dan の回答は機能しますが、この線形インデックス方法を使用して解決策があるかどうかを確認したいと思います。

% Example data
M=round(randn(11,11,11))~=0;

% Fancy way of storing 26 neigh indices for good accesing 
s=size(M);
N=length(s);
[c1{1:N}]=ndgrid(1:3);
c2(1:N)={2};
neigh26=sub2ind(s,c1{:}) - sub2ind(s,c2{:});

point=[5 1 6];

% This will work unless the point is in the boundary (like in this example)
neighbours=M(sub2ind(s,point(1),point(2),point(3))+neigh26) 
4

2 に答える 2

3

その線形索引付けは不可欠ですか? 境界条件を処理するのは非常に簡単なので、添字インデックスを使用するとminmax次のようになります。

p = [5, 1, 6];

neighbourhood = M(max(1,p(1)-1)):min(p(1)+1,end),
                  max(1,p(2)-1)):min(p(2)+1,end),
                  max(1,p(3)-1)):min(p(3)+1,end))

%// Get rid of the point it self (i.e. the center)
neighbours = neighbourhood([1:13, 15:end])

このようにして、より広い範囲が必要な場合は、これを簡単に一般化することもできます。

p = [5, 1, 6];
n = 2;
neighbourhood = M(max(1,p(1)-n)):min(p(1)+n,end),
                  max(1,p(2)-n)):min(p(2)+n,end),
                  max(1,p(3)-n)):min(p(3)+n,end))

%// Get rid of the point it self (i.e. the center)
mid = ceil(numel(neigbourhood)/2);
neighbours = neighbourhood([1:mid-2, mid+1:end])

または、立方体の形状を維持したい場合は、次のようにします。

neighbours = neighbourhood;
neighbours(mid) = NaN;

これをコードで何度も使用する場合は、インデックスを返すだけの m ファイル関数としてリファクタリングするのがおそらく最善です。

function ind = getNeighbours(M,p,n)
    M = zeros(size(M));
    M(max(1,p(1)-n)):min(p(1)+n,end), max(1,p(2)-n)):min(p(2)+n,end), max(1,p(3)-n)):min(p(3)+n,end)) = 1;
    M(p(1), p(2), p(3)) = 0;
    ind = find(M);
end
于 2014-10-17T11:36:09.593 に答える
1

Basic theory: Extend input array to left-right, up-down, one more on each sides of the third dimension with NaNs. This would allow us to use a uniform 3x3x3 grid and then later on use those NaNs to detect elements that go beyond the boundaries of input array and as such are to be discarded.

Code

%// Initializations
sz_ext = size(M)+2; %// Get size of padded/extended input 3D array
M_ext = NaN(sz_ext); %// Initialize extended array
M_ext(2:end-1,2:end-1,2:end-1) = M; %// Insert values from M into it

%// Important stuff here : Calculate linear offset indices within one 3D slice
%// then for neighboring 3D slices too
offset2D = bsxfun(@plus,[-1:1]',[-1:1]*sz_ext(1)); %//'
offset3D = bsxfun(@plus,offset2D,permute([-1:1]*sz_ext(1)*sz_ext(2),[1 3 2]));

%// Get linear indices for all points
points_linear_idx = sub2ind(size(M_ext),point(:,1)+1,point(:,2)+1,point(:,3)+1);
%// Linear indices for all neighboring elements for all points; index into M_ext
neigh26 = M_ext(bsxfun(@plus,offset3D,permute(points_linear_idx,[4 3 2 1])))

How to use: Thus, each slice in the 4th dimension represent the 27 elements (neighboring plus the element itself) as 3x3x3 array. Hence, neigh26 would be a 3x3x3xN array where N is the number of points in point array.

Example: As an example, let's assume some random values in M and Point -

M=rand(11,11,11);
point = [
    1 1 4;
    1 7 1]

On running the earlier code with these inputs, I get something like this -

neigh26(:,:,1,1) =
       NaN       NaN       NaN
       NaN    0.5859    0.4917
       NaN    0.6733    0.6688
neigh26(:,:,2,1) =
       NaN       NaN       NaN
       NaN    0.0663    0.5544
       NaN    0.3440    0.3664
neigh26(:,:,3,1) =
       NaN       NaN       NaN
       NaN    0.3555    0.1257
       NaN    0.4424    0.9577
neigh26(:,:,1,2) =
   NaN   NaN   NaN
   NaN   NaN   NaN
   NaN   NaN   NaN
neigh26(:,:,2,2) =
       NaN       NaN       NaN
    0.7708    0.3712    0.2866
    0.7088    0.3743    0.2326
neigh26(:,:,3,2) =
       NaN       NaN       NaN
    0.4938    0.5051    0.9416
    0.1966    0.0213    0.8036
于 2014-10-17T16:44:56.497 に答える