0

在执行 3D CT 的分水岭后,我只选择小于某个值且大于另一个值的粒子。然而,作为最终输出,我需要一个仅包含连续 ID 的矩阵。我的实现如下:

% Get unique IDs
grain_id = unique(L);

% Get rid of artefacts
% Compute histogram for each ID
% and compare volume numv with thresholds

% Reject grains smaller or larger than threshold
reject = grain_id(or(numv<vmin,numv>vmax));

% Keep 0s (boundaries) and 1 (voids)
reject = reject(3:end);        

% Rejected become void
L(ismember(L,reject))=1;

% Get number of grains
grain_id = unique(L);
numgrains = numel(grain_id);

% Consecutive IDs
idx = false(size(L));
for i=1:numel(reject)
    idx = L>reject(numel(reject)+1-i);
    L = L-uint16(idx);
end

我有一个 1226x1226x3600 矩阵,所以性能真的很重要。一个循环大约需要。5秒。这很可能不是实现目标的最有效方法,但目前我没有更好的想法。你?

4

1 回答 1

1

如果我正确理解您的问题陈述,这正是该函数的第三个输出的unique用途。unique它检查您的数据,并且对于每个元素,第三个输出提供一个映射,告诉您对应元素需要哪个索引到输出中。巧合的是,这提供了一个新的整数映射,它1与输入中的唯一标签一样多是连续的。

但是,对于除作为输入的向量之外的任何内容,这将作为列展开向量返回,unique因此您需要将reshape其返回到与最后的输入相同的维度。

因此,您需要的只是:

[~,~,id] = unique(L);
id = reshape(id, size(L));

idL将是与您用作输入的矩阵大小相同的矩阵L

这是一个玩具示例,以确保我们在同一页面上:

>> rng(123); L = randi(50, 10, 10)

L =

    35    18    32     5    32     7    34     5    16    36
    15    37    43    22     6    42    30    45    35    50
    12    22    37    22    16    31    32    32    28    18
    28     3    31    25    21    28    34    37    20    39
    36    20    37    22    44    18    43     1    47    30
    22    37    17    16    13    16     5    30    43    35
    50    10    19    22    25    21    39    28    18     8
    35     9    12    45    50    35    13     8     3    20
    25    27    15    48    26    44    10     8    16    13
    20    27    32    26    31    26    29    35    20    18

在这里,我创建了一个 10 x 10 不连续的随机数矩阵。我们可以通过查看此矩阵中的所有唯一数字来看到这一点:

>> unique(L).'

ans =

  Columns 1 through 19

     1     3     5     6     7     8     9    10    12    13    15    16    17    18    19    20    21    22    25

  Columns 20 through 38

    26    27    28    29    30    31    32    34    35    36    37    39    42    43    44    45    47    48    50

例如,请注意从 1 到 3 或从 13 到 15 的跳跃。通过执行我上面写的代码,我们现在得到:

>> id

id =

    28    14    26     3    26     5    27     3    12    29
    11    30    33    18     4    32    24    35    28    38
     9    18    30    18    12    25    26    26    22    14
    22     2    25    19    17    22    27    30    16    31
    29    16    30    18    34    14    33     1    36    24
    18    30    13    12    10    12     3    24    33    28
    38     8    15    18    19    17    31    22    14     6
    28     7     9    35    38    28    10     6     2    16
    19    21    11    37    20    34     8     6    12    10
    16    21    26    20    25    20    23    28    16    14

正如您在此处看到的,标签 3 变为标签 2 以确保标签是连续的。同样,标签 13 和 15 变为 10 和 11 以确保您需要的连续顺序,依此类推。可以肯定的是,这里是输出中所有唯一值的列表:

>> unique(id).'

ans =

  Columns 1 through 19

     1     2     3     4     5     6     7     8     9    10    11    12    13    14    15    16    17    18    19

  Columns 20 through 38

    20    21    22    23    24    25    26    27    28    29    30    31    32    33    34    35    36    37    38
于 2017-01-18T09:39:26.507 回答