【问题标题】:Matlab - Propagate points orthogonally on to the edge of shape boundariesMatlab - 将点正交传播到形状边界的边缘
【发布时间】:2011-02-09 12:08:12
【问题描述】:

我有一组点,我想将它们传播到由二进制图像定义的形状边界的边缘。形状边界由 1px 宽的白色边缘定义。

我将这些点的坐标存储在一个 2 行乘 n 列的矩阵中。该形状形成一个凹形边界,其内部没有孔,由大约 2500 个点组成。我希望在形状边界上传播大约 80 到 150 个点。

我想从一组点中的每个点沿正交方向投射一条射线,并检测它与形状边界的交点。正交方向已经确定。出于所需的目的,它是使用为点计算的轮廓的法线计算的,使用点 1 和点 + 1。

最好的方法是什么? 是否有某种可以使用的光线追踪算法?

非常感谢您的任何帮助!

编辑:我试图使问题更清晰,并添加了描述问题的图像。图中灰线表示形状轮廓,红点表示点 我想传播,绿线是一条假想的正交投射射线。

alt text http://img504.imageshack.us/img504/3107/orth.png

另一个编辑:为澄清起见,我发布了用于计算每个点的法线的代码。其中 xt 和 yt 是存储每个点的坐标的向量。计算出正常值后,可以使用 linspace 函数和所要求的正交线长度进行传播。

%#derivaties of contour
dx=[xt(2)-xt(1) (xt(3:end)-xt(1:end-2))/2 xt(end)-xt(end-1)];
dy=[yt(2)-yt(1) (yt(3:end)-yt(1:end-2))/2 yt(end)-yt(end-1)];

%#normals of contourpoints
l=sqrt(dx.^2+dy.^2);
nx = -dy./l; 
ny =  dx./l;

normals = [nx,ny];

【问题讨论】:

  • 绿线与什么正交? “正交方向已经确定”是指我们可以将其视为给定的数据的一部分吗?

标签: matlab image-processing raytracing point propagation


【解决方案1】:

这取决于您要针对一种形状测试多少个单位向量。如果您有一个形状和许多测试,最简单的方法可能是将您的形状坐标转换为已经隐式表示您的解决方案的极坐标。这可能不是一个非常有效的解决方案,但是如果您有不同的形状并且每个形状只进行几次测试。

根据修改后的问题更新:

如果光线可以从任意点开始,而不仅仅是从原点,您必须针对所有点进行测试。这可以通过转换形状边界来轻松完成,这样要测试的光线从任意坐标方向的原点开始(在我的示例代码中为正 x)

% vector of shape boundary points (assumed to be image coordinates, i.e. integers)
shapeBoundary = [xs, ys];

% define the start point and direction you want to test
startPoint = [xsp, ysp];
testVector = unit([xv, yv]);

% now transform the shape boundary
shapeBoundaryTrans(:,1) = shapeBoundary(:,1)-startPoint(1);
shapeBoundaryTrans(:,2) = shapeBoundary(:,2)-startPoint(2);
rotMatrix = [testVector(2), testVector(1); ...
             testVector(-1), testVector(2)];
% somewhat strange transformation to keep it vectorized
shapeBoundaryTrans = shapeBoundaryTrans * rotMatrix';

% now the test is easy: find the points close to the positive x-axis
selector = (abs(shapeBoundaryTrans(:,2)) < 0.5) & (shapeBoundaryTrans(:,1) > 0);
shapeBoundaryTrans(:,2) = 1:size(shapeBoundaryTrans, 1)';
shapeBoundaryReduced = shapeBoundaryTrans(selector, :);
if (isempty(shapeBoundaryReduced))
    [dummy, idx] = min(shapeBoundaryReduced(:, 1));
    collIdx = shapeBoundaryReduced(idx, 2);
    % you have a collision with point collIdx of your shapeBoundary
else
    % no collision
end

这可能会以更好的方式完成,但你明白了......

【讨论】:

  • 啊!我真的很抱歉我错误地陈述了我的问题。我已经创建了一个新的编辑版本。我有 80 到 200 个点我希望正交投射和大约。 2500点测试。抱歉发错了帖子,我很想知道你对这个问题的看法。
  • 在您编辑问题后,我仍然认为我更新的答案应该大致符合您的要求(但是自己没有尝试过......)当您再次编辑您的问题时,一定有一些东西我的答案不见了。你能澄清一下什么不起作用吗?
  • 抱歉编辑量很大。我发现很难说出一个我不熟悉的问题。我添加了如何计算法线和图表。我认为您的解决方案不起作用,因为它仅基于选定的一个轴进行搜索。希望对您有所帮助,感谢您的坚持!
  • 据我了解,您的问题基本上归结为找到一条直线(射线)与给定多边形(形状轮廓)的交点。在任何情况下,您都必须测试光线是否与任何多边形线段相交。我建议通过旋转多边形(形状轮廓)来简化测试,使光线与一个轴对齐,并假设线段足够短,因此无论您是针对线段还是角进行测试都没有关系点。
【解决方案2】:

如果我正确理解您的问题(将每个点投影到形状边界的最近点上),您可以

  1. 使用sub2ind 将“2 行 x n 列矩阵”描述转换为具有白色像素的 BW 图像,类似于

    myimage=zeros(imagesize); myimage(imagesize, x_coords, y_coords) = 1

  2. 使用imfill填充边界的外侧

  3. 在生成的图像上运行[D,L] = bwdist(BW),然后从L 中读取答案。

应该相当简单。

【讨论】:

  • 技术上可能不赌形状边界的闭合点。我添加了一个图表以更清楚地了解问题...
  • @Graham:绿线与什么正交?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
相关资源
最近更新 更多