在对三角形曲面进行二次采样时保留颜色:从reducepatch获取索引?

时间:2017-03-05 21:22:52

标签: matlab vectorization triangulation

我有一个非常密集的镶嵌表面,看起来像这样: White matter dense

这个表面对我来说太密集了,所以我对它进行二次取样以获得更粗糙的表面。为此,我使用了Matlab的reducepatch函数。这非常有效: White matter subsampled

不幸的是,着色是基于一个名为sulcal_depth的变量,它是为我的镶嵌曲面的每个顶点定义的。因此,我只需要保留二次采样后保留的顶点的深度信息。基本上,我需要reducepatch不仅给我表面的二次采样版本,还给它保留的顶点的索引。如果我知道保留的索引,我可以将我的sulcal_depth变量编入索引以获取新的深度图。

目前,我按照以下方式执行此操作(这也是我对上面的二次采样版本进行着色的方式):

function indices = compute_reduced_indices(before, after)
%% Function to compute the indices of vertices preserved during an operation of
%  reducepatch. This allows you to use reducepatch to subsample a surface and
%  re-compute an original signal on the vertices for the new subsampled mesh

indices = zeros(length(after), 1);
for i = 1:length(after)
    dotprods = (before * after(i, :)') ./ sqrt(sum(before.^2, 2));
    [~, indices(i)] = max(dotprods);
end

但正如您可能想象的那样,这是非常缓慢的,因为顶点上的for循环。我没有足够的内存来矢量化循环并一次性计算完整的点积矩阵。

是否有一种聪明的方法可以让reducepatch为我提供指数或替代方法(有或没有reducepatch)更快?

1 个答案:

答案 0 :(得分:3)

如果reducepath仅删除某些顶点但未更改保留点的坐标,则可以使用函数ismember

%Load the "flow" matlab's dataset.
[x,y,z,v] = flow(100);
%Patch the isosurface
p = patch(isosurface(x,y,z,v,-3));
%Reducepatch
rp = reducepatch(p,0.15);
%Create an index of the preserved vertex.
[ind,loc] = ismember(p.Vertices,rp.vertices,'rows'); 
%Checksum
sum(find(ind) == sort(indices)) == length(indices) %should be = 1

%if you want to preserve the index order:
locb = loc(ind);
subind = find(ind);
[~,revsor] = sort(locb);
ind = subind(revsor);

<强> BENCHMARKING

[x,y,z,v] = flow(100);

p = patch(isosurface(x,y,z,v,-3));
rp = reducepatch(p,0.15);
tic
ind = ismember(p.Vertices,rp.vertices,'rows');
toc

before = p.Vertices;
after = rp.vertices;

tic 
indices = zeros(length(after), 1);
for i = 1:length(after)
    dotprods = (before * after(i, :)') ./ sqrt(sum(before.^2, 2));
    [~, indices(i)] = max(dotprods);
end
toc

<强> RESULT

Elapsed time is 0.196078 seconds. %ismember solution 
Elapsed time is 11.280293 seconds. %dotproduct solution