Matlab - 将点正交传播到形状边界的边缘

发布于 2024-08-29 12:09:17 字数 907 浏览 12 评论 0原文

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

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

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

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

预先非常感谢您的帮助!

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

替代文本 http://img504.imageshack.us/img504/3107/orth.png< /a>

另一个编辑:为了澄清,我发布了用于计算每个点的法线的代码。其中 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];

I have a set of points which I want to propagate on to the edge of shape boundary defined by a binary image. The shape boundary is defined by a 1px wide white edge.

I have the coordinates of these points stored in a 2 row by n column matrix. The shape forms a concave boundary with no holes within itself made of around 2500 points. I have approximately 80 to 150 points that I wish to propagate on the shape boundary.

I want to cast a ray from each point from the set of points in an orthogonal direction and detect at which point it intersects the shape boundary at. The orthogonal direction has already been determined. For the required purposes it is calculated taking the normal of the contour calculated for point, using point-1 and point+1.

What would be the best method to do this?
Are there some sort of ray tracing algorithms that could be used?

Thank you very much in advance for any help!

EDIT: I have tried to make the question much clearer and added a image describing the problem. In the image the grey line represents the shape contour, the red dots the points
I want to propagate and the green line an imaginary orthongally cast ray.

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

ANOTHER EDIT: For clarification I have posted the code used to calculate the normals for each point. Where the xt and yt are vectors storing the coordinates for each point. After calculating the normal value it can be propagated by using the linspace function and the requested length of the orthogonal line.

%#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];

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

俯瞰星空 2024-09-05 12:09:17

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

根据编辑的问题进行更新

如果光线可以从任意点开始,而不仅仅是从原点开始,则必须针对所有点进行测试。这可以通过转换形状边界轻松完成,以便要测试的光线从任一坐标方向的原点开始(我的示例代码中的正 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

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

It depends on how many unit vectors you want to test against one shape. If you have one shape and many tests, the easiest thing to do is probably to convert your shape coordinates to polar coordinates which implicitly represent your solution already. This may not be a very effective solution however if you have different shapes and only a few tests for every shape.

Update based on the edited question:

If the rays can start from arbitrary points, not only from the origin, you have to test against all the points. This can be done easily by transforming your shape boundary such that your ray to test starts in the origin in either coordinate direction (positive x in my example code)

% 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

This could be done in a nicer way probably, but you get the idea...

巾帼英雄 2024-09-05 12:09:17

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

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

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

  2. 使用 imfill 填充边界外部

  3. 在生成的图像上运行 [D,L] = bwdist(BW),然后读取 < code>L.

应该相当简单。

If I understand your problem correctly (project each point onto the closest point of the shape boundary), you can

  1. use sub2ind to convert the "2 row by n column matrix" description to a BW image with white pixels, something like

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

  2. use imfill to fill the outside of the boundary

  3. run [D,L] = bwdist(BW) on the resulting image, and just read the answers from L.

Should be fairly straightforward.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文