如何使用两个边界数组有效地创建非线性蒙版

时间:2019-06-05 19:58:05

标签: matlab for-loop optimization

我可以基于包含掩模上下边界的两个数组制作一个非线性掩模。介于两者之间的所有值都必须设置为1。我现在执行此操作的方法似乎要花费大量时间,并且正在成为瓶颈。我想知道是否有一种方法可以更节省时间。

首先,我正在考虑使用parfors解决该问题以提高速度。但是,由于这是我代码中的内部循环之一,因此它们似乎效率很低,因为考虑到计划开销,在外部循环上使用parfor更为可行。因此并行技术不是一种选择。

请参见此处创建蒙版:

mask = zeros(size(im));
n = length(bufLow);

for i=1:1:n                 
   mask(bufLow(i):bufHigh(i),i) = 1;
end    

im 是一定大小的矩阵,而 bufLow bufHigh 是大小等于 im水平大小的数组描述 im 每列的上下边界。在这些值之间,所有内容都需要设置为1。

所以目标是要有一些办法尽可能减少此循环的执行时间。我想知道是否有人能启发我。

最好

Matthijs

1 个答案:

答案 0 :(得分:1)

我承认,您的问题允许进行一些解释和猜测,但是从您提供的代码中,我有一个想法,您想要实现的目标:对于{{1}中的第i列},您希望将起始索引(即mask)和结束索引(bufLow(i))之间的所有像素都设置为1。对吗?

因此,我对循环进行“向量化”的想法是将bufHigh(i)中的“每列”下标(或数组)索引转换为“ image” linear indices,然后找到所有线性索引在开始索引和结束索引之间。后者是一个(常见)问题,已经有几个重要的答案,例如this one from Divakar

我将他的答案纳入了我的解决方案中。请查看以下代码:

bufxxx

生成的蒙版是相同的,看起来像这样:

Mask

要查看性能,我使用两种方法设置了单独的计时脚本,将维度dim = 25; bufLow = int32(10 * rand(1, dim) + 1); bufHigh = int32(10 * rand(1, dim) + 15); % Reference implementation from question mask = zeros(dim); n = length(bufLow); for i=1:1:n mask(bufLow(i):bufHigh(i), i) = 1; end % Show mask figure(1); imshow(mask); % Implementation using Divakar's approach % Translate subscript indices to linear indices bufLow = bufLow + (dim .* (0:dim-1)); bufHigh = bufHigh + (dim .* (0:dim-1)); % Divakar's approach for finding all indices between two boundaries lens = bufHigh - bufLow + 1; shift_idx = cumsum(lens(1:end-1)) + 1; id_arr = ones(1, sum(lens)); id_arr([1 shift_idx]) = [bufLow(1) bufLow(2:end) - bufHigh(1:end-1)]; out = cumsum(id_arr); % Generating mask mask2 = zeros(dim); mask2(out) = 1; % Show mask figure(2); imshow(mask2); 从25增加到2500,以25为步长。结果如下:

Comparison

希望有帮助!