首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何为任何二维形状(或曲线)生成阶梯曲线(轮廓)?

如何为任何二维形状(或曲线)生成阶梯曲线(轮廓)?
EN

Stack Overflow用户
提问于 2017-07-20 10:01:22
回答 2查看 416关注 0票数 2

如果我有任意2D形状轮廓上的点的坐标,如何找到构成楼梯阶梯曲线轮廓的点的坐标,它最好地表示原始轮廓,但仅使用一组已知坐标(xi,i=1,...,n和yi,i=1,...,m)。例如,原始三角形由粗的蓝色实线表示。如果我的理解正确的话,它与matlab的楼梯函数是不同的。matlab代码会不错,但用其他语言也可以,算法最important.Thanks。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-21 13:56:47

首先,我将根据您的图定义一组样本数据。假设像素中心以整数值对齐( MATLAB遵循的约定),并且左下角为(0.5, 0.5),下面是我们获得的数据:

代码语言:javascript
运行
复制
vx = [1.5; 9.7; 3.7; 1.5];  % X values of triangle vertices
vy = [8.3; 6.0; 1.7; 8.3];  % Y values of triangle vertices
x = 1:10;                   % X pixel center coordinates
y = 1:9;                    % Y pixel center coordinates

请注意,顶点坐标是从三角形的左上角开始按顺时针方向排列的,重复末端的第一个顶点以闭合多边形。

获取掩码(最简单的部分):

如果你有Image Processing Toolbox,有一个计算深灰色蒙版的简单方法:使用poly2mask

代码语言:javascript
运行
复制
mask = poly2mask(vx, vy, numel(y), numel(x));

此函数使用的算法在here中进行了讨论。但是,如果您希望使用不需要特殊工具箱的纯MATLAB方法,则可以使用inpolygon

代码语言:javascript
运行
复制
[cx, cy] = meshgrid(x, y);         % Generate a grid of x and y values
mask = inpolygon(cx, cy, vx, vy);

在这种情况下,只要像素的中心点位于多边形内,该像素就会包含在遮罩中。在这个特定的例子中,这两种方法产生相同的结果掩码,但它们并不总是由于它们决定是否包含像素的标准的差异。

获取轮廓坐标:

获取遮罩轮廓的坐标要稍微复杂一些,并在周长周围进行适当的排序。为此,我们可以将蒙版表示为一系列顶点和三角面(使用triangulation函数),然后计算free boundary (即仅存在于一个三角面上的边):

代码语言:javascript
运行
复制
% Create raw triangulation data:
[cx, cy] = meshgrid(x, y);
xTri = bsxfun(@plus, [0; 1; 1; 0], cx(mask).');
yTri = bsxfun(@plus, [0; 0; 1; 1], cy(mask).');
V = [xTri(:) yTri(:)];
F = reshape(bsxfun(@plus, [1; 2; 3; 1; 3; 4], 0:4:(4*nnz(mask)-4)), 3, []).';

% Trim triangulation data:
[V, ~, Vindex] = unique(V, 'rows');
V = V-0.5;
F = Vindex(F);

% Create triangulation and find free edge coordinates:
TR = triangulation(F, V);
freeEdges = freeBoundary(TR).';
xOutline = V(freeEdges(1, [1:end 1]), 1);  % Ordered edge x coordinates
yOutline = V(freeEdges(1, [1:end 1]), 2);  % Ordered edge y coordinates

我们可以这样画这个图:

代码语言:javascript
运行
复制
imagesc(x, y, mask);
axis equal
set(gca, 'XLim', [min(x)-0.5 max(x)+0.5], ...
         'YLim', [min(y)-0.5 max(y)+0.5], ...
         'XTick', x, 'YTick', y, 'YDir', 'normal');
colormap([0.9 0.9 0.9; 0.6 0.6 0.6]);
hold on;
plot(xOutline, yOutline, 'b', 'LineWidth', 2);
plot(xOutline(1), yOutline(1), 'go', 'LineWidth', 2);
plot(vx, vy, 'r', 'LineWidth', 2);

xOutlineyOutline中的轮廓坐标从围绕遮罩区域逆时针旋转的绿色圆圈开始排序。

票数 2
EN

Stack Overflow用户

发布于 2017-07-20 10:33:01

似乎你需要任何线条光栅化算法(给出近似线段的整数网格点的坐标)。

考虑Bresenham算法或DDA算法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45203862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档