对三角化表面进行子采样时保留颜色:从 reducepatch 获取索引?
Retaining color when subsampling a triangulated surface: get indices from reducepatch?
我有一个非常密集的镶嵌曲面,看起来像这样:
这个表面对我来说太密集了,所以我对它进行二次采样以获得更粗糙的表面。为此,我使用了 Matlab 的 reducepatch
函数。这很好用:
不幸的是,着色基于一个名为 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
)?
如果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);
基准测试
[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
结果
Elapsed time is 0.196078 seconds. %ismember solution
Elapsed time is 11.280293 seconds. %dotproduct solution
我有一个非常密集的镶嵌曲面,看起来像这样:
这个表面对我来说太密集了,所以我对它进行二次采样以获得更粗糙的表面。为此,我使用了 Matlab 的 reducepatch
函数。这很好用:
不幸的是,着色基于一个名为 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
)?
如果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);
基准测试
[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
结果
Elapsed time is 0.196078 seconds. %ismember solution
Elapsed time is 11.280293 seconds. %dotproduct solution