【问题标题】:extraction of minimal bounding box最小边界框的提取
【发布时间】:2015-05-09 18:13:54
【问题描述】:

我有一个体积(图像)和一个最小边界框,它包裹着某种结构。 我使用以下算法提取最小边界框

http://uk.mathworks.com/matlabcentral/fileexchange/18264-minimal-bounding-box/content/minboundbox.m

这样我得到一个看起来像这样的边界框

现在,我想从 MBB 创建一个新卷。换句话说,我想将 MBB 中的每个点映射到一个轴平行的新框。

我可以从角点得到新盒子的尺寸

 dim = [0 0 0];
 x = cp(:,1);
 y = cp(:,2);
 z = cp(:,3);
 dim(3) = sqrt( (x(1)-x(2))^2 + (y(1)-y(2))^2 + (z(1)-z(2))^2 );
 dim(1) = sqrt( (x(1)-x(4))^2 + (y(1)-y(4))^2 + (z(1)-z(4))^2 );
 dim(2) = sqrt( (x(1)-x(5))^2 + (y(1)-y(5))^2 + (z(1)-z(5))^2 );

现在,我可以应用 minboundbox 算法返回的旋转矩阵了,

 A = zeros(4,4); A(1:3, 1:3) = R; A(4,4) = 1;
 tform = affine3d(A);
 N = numel(img);
 [X,Y,Z] = ind2sub(size(img), 1:N);
 V = img(1:N);
 [Xt, Yt, Zt] = transformPointsForward (tform,X,Y,Z);
 Xt = reshape(Xt, size(img));
 Yt = reshape(Yt, size(img));
 Zt = reshape(Zt, size(img));

现在我被困住了。我需要:

  • 在规则网格中插入与这些坐标相关的值(我尝试的任何方法都出现内存不足,图像具有以下大小=(300,400,500));

  • 仅提取 MBB 的区域。

知道我该怎么做吗?

UPDATE主要问题不是如何获取 Xt、Yt、Zt...

问题,由于 Xt、Yt 和 Zt 形成了一个不规则的点网格,并关联了某些值,我怎样才能得到一个带有插值点的规则网格?我试过了,但内存不足

Vq = griddata(Xt, Yt, Zt, double(V), 1:dim(1), 1:dim(2), 1:dim(3));

【问题讨论】:

  • 你有多少分?您是否尝试过仅测量执行该命令实际需要多少内存并查看您的系统是否首先支持它?
  • 31000000 点...给予或接受.... 但是,它们是否必须同时放入内存中?我认为并且我希望它只在本地进行插值,而不是在全球范围内。
  • AFAIK,没有函数可以在不手动循环子区域并执行插值的情况下进行本地插值。是的,它们确实必须适合内存+页面文件;您是否尝试过在转换后清除旧的 (X,Y,Z) 数据?这可以节省你的记忆。
  • 是的,我没有内存不足,但需要的时间太长了。我没有设法得到结果(30 分钟后我启动了命令)等等等等……如果你做简单的插值,你不需要加载整个东西。你呢?我可能错了,我还在研究这些东西:-)
  • 通常插值是本地的,所以是的。您需要围绕插值区域的点区域取决于您执行的插值类型(更高阶 = 需要更多点)。

标签: matlab image-processing bounding-box


【解决方案1】:

如果您只想提取 MBB 的区域,将 MBB 的空间映射到单位立方体会更容易。这是我的做法(请注意,这主要是伪代码,不能保证它有效。我很快会在另一台计算机上的 matlab 实例上试用它...)

Translation = eye(4)
Translation(1:3, 4) = transpose(-cornerpoints(1,:))

BoxAxisX = transpose(cornerpoints(:,4) - cornerpoints(:,1))
BoxAxisX = BoxAxisX / norm(BoxAxisX)

BoxAxisY = transpose(cornerpoints(:,5) - cornerpoints(:,1))
BoxAxisY = BoxAxisY / norm(BoxAxisY)

BoxAxisZ = transpose(cornerpoints(:,2) - cornerpoints(:,1))
BoxAxisZ = BoxAxisZ / norm(BoxAxisZ)

Rotation = eye(4)
Rotation(1:3,1:3) = [ BoxAxisX, BoxAxisY, BoxAxisZ ]

Scale = diag( [ (1/dim(1)) (1/dim(2)) (1/dim(3)) 1 ] )

A = affine3d( Scale * Rotation * Translation )

[Xt, Yt, Zt] = transformPointsForward (A,X,Y,Z);

% Now all your points that are within the box should satisfy unit constraints
GoodIndices = Xt <= 1 && Xt >= 0 && Yt <= 1 && Yt >= 0 && Zt <= 1 && Zt >= 0
GoodX = Xt(GoodIndices)
...

一般的想法是把盒子变回一个单位立方体,一个点在原点。步骤如下:

  • 选择一个基点;这将成为你的起源。
  • 从构成框边界的基点查找向量;这是您当前的坐标系。
  • 根据这些向量构造旋转矩阵;这是使用您选择的基点从标准基向量 (X,Y,Z) 到框旋转的矩阵。反转这个矩阵。
  • 将框向后平移,使基点现在位于原点
  • 现在使用反向旋转矩阵并将其应用于您的盒子。
  • 请注意,您的框现在在原点轴对齐。现在您需要做的就是适当地缩放您的盒子。

我不使用他们给出的旋转矩阵的原因是我真的不知道它会走向哪个轴以及它围绕什么点旋转(围绕原点旋转!什么!)。所以...使用您知道的角点构建旋转矩阵更容易,您可以选择基点。

至于内存不足异常...有很多关于如何减少内存使用的帖子。这张图片虽然很大..(~240MB)

【讨论】:

  • 好的,但主要问题不是如何获得 Xt、Yt、Zt(尽管我真的很欣赏你的方法,它比我的更清晰)问题,因为 Xt、Yt 和 Zt 形成了一个不规则的点网格,具有关联的某些值,我怎样才能得到一个带有插值点的规则网格?我会把这个添加到问题中
猜你喜欢
  • 2021-04-16
  • 2014-07-17
  • 2014-01-11
  • 2020-12-08
  • 1970-01-01
  • 2023-02-25
  • 2019-08-26
  • 1970-01-01
  • 2021-04-15
相关资源
最近更新 更多