凸包内人工块的查询量
Posted
技术标签:
【中文标题】凸包内人工块的查询量【英文标题】:Query volume of artifical blocks inside a convex hull 【发布时间】:2017-01-28 11:48:04 【问题描述】:问题:
我有一个三维点云,每个块的质心代表一个块。为简单起见,这个例子只是二维的。 如图所示,我想根据参数包含感兴趣的块。在此处的情况下,块 1、6、5、4。为了进一步处理它们,我需要通过使用 alpha 形状或凸包来找到它们周围的最小外壳。我有每个质心的坐标,我知道块扩展,所以我可以通过以下方式轻松找到块的边缘点:
xdimension=5;
ydimension=5;
block1=[5 15 1];
block2=[5 10 0];
block3=[5 5 0];
block4=[10 5 1];
block5=[10 10 1];
block6=[10 15 1];
block7=[15 5 0];
block8=[15 10 0];
block9=[15 15 0];
blocks=[block1;block2;block3;block4;block5;block6;block7;block8;block9]
dimension=[xdimension/2 ydimension/2];
point1=[1 1].*dimension;
point2=[1 -1].*dimension;
point3=[-1 1].*dimension;
point4=[-1 -1].*dimension;
i=size(blocks,1);
point1=repmat(point1,i,1);
point2=repmat(point2,i,1);
point3=repmat(point3,i,1);
point4=repmat(point4,i,1);
edges1=[blocks(:,1:2)+point1, blocks(:,3)] ;
edges2=[blocks(:,1:2)+point2, blocks(:,3)];
edges3=[blocks(:,1:2)+point3, blocks(:,3)];
edges4=[blocks(:,1:2)+point4, blocks(:,3)];
edges=[edges1;edges2;edges3;edges4];
x=edges(edges(:,3)==1,1);
y=edges(edges(:,3)==1,2);
K=convhull(x,y)
scatter(edges(:,1), edges(:,2))
hold on
plot(x(K),y(K),'r-')
hold off
这会生成一张与此处类似的图片。
问题
如何查询块 2 和 3 的凸包所包含的表面(或在我的实际问题中的体积)?我需要每个 individual 块的确切表面/体积,除了我指定的那些块(这里是二进制指标)。 请注意,这是一个示例,我正在寻找如何独立于示例执行此操作的想法。我真的很感激一些帮助,因为我主要被困在这里,我不知道如何解决它。
【问题讨论】:
【参考方案1】:在 2D 中,我会使用 inpolygon 函数来测试一个点是否在凸包与正方形 2 和 3 的交点内。
对于 3D,我在 MATLAB 中没有找到等效的解决方案,但下面的 matlab exchange file 应该是解决方案。
如何使用函数 inhull 查找内部区域的点的示例:
% Create a 3D cube
cubePoints = randi(5,[500,3]);
% Bounding volume
boundingVolume = zeros(8,3);
boundingVolume(1,:) = [1,3,1];
boundingVolume(2,:) = [1,3,3];
boundingVolume(3,:) = [3,3,1];
boundingVolume(4,:) = [3,3,3];
boundingVolume(5,:) = [3,1,3];
boundingVolume(6,:) = [3,1,1];
boundingVolume(7,:) = [2,1,1];
boundingVolume(8,:) = [2,1,3];
% Find points inside area
inVol = inhull(cubePoints,boundingVolume);
% Plot the point in the bounding volume in blue and the points outsode the
% bounding volume in red
scatter3(cubePoints(:,1).*inVol,cubePoints(:,2).*inVol,cubePoints(:,3).*inVol,36,'blue');
hold on
scatter3(cubePoints(:,1).*~inVol,cubePoints(:,2).*~inVol,cubePoints(:,3).*~inVol,36,'red');
【讨论】:
这是一个不错的开始,但是根据这些点,您如何才能准确地获得包含块的表面/体积?使用单个边缘点将是一个近似值,但取决于船体的大小非常不准确 虽然这在理论上可以回答问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。【参考方案2】:我相信这种方法是可行的,但是如果系统很大,就内存消耗而言,它没有什么可炫耀的:
首先以 3d 二进制数组的形式构造总的凸包。。此外,每个块应该在整个空间上形成一个 3d 二进制数组,true
元素在块的扩展范围内,false
在其他地方。 (要完成此操作,请检查 Amitay's answer 中的 link。)
现在您可以从中计算每个区块的份额。如果你按照解释形成了所有东西,剩下的就很简单了:你可以直接计算conv
与每个block
的重叠,如下所示:
num = numel(block);
shareofblock = zeros(num, 1);
for jj = 1:num
overlap = block(jj) & conv;
shareofblock(jj) = sum(overlap(:));
end
【讨论】:
【参考方案3】:如果您成功找到了您的 covex 外壳(使用 convhull
函数),它的第二个输出变量将为您提供所需的 (?)。
[IDs,V] = convhull(X,Y,Z)
这里的V
是包围在点(X,Y,Z)
的凸包中的体积。祝福 Matlab!
【讨论】:
我知道,问题是我想知道 2 和 3 分别包含的确切数量,而不是总量。 ;)以上是关于凸包内人工块的查询量的主要内容,如果未能解决你的问题,请参考以下文章
2022最新《人工智能入门指南》全套学习教程,全网阅读量10w+