如果我有任意2D形状轮廓上的点的坐标,我怎样才能找到构成阶梯曲线轮廓的点的坐标,它最能代表原始轮廓,但只能使用一组已知坐标(xi,i = 1,...,n和yi,i = 1,...,m)。例如,原始三角形由粗实线蓝色表示。如果我的理解是正确的,它与matlab楼梯功能有所不同。 matlab代码会很好,但在其他语言中也行,算法最重要。谢谢。
答案 0 :(得分:2)
首先,我将根据您的情节定义一组样本数据。假设像素中心以整数值对齐(遵循惯例MATLAB)并且左下角位于(0.5, 0.5)
,这是我们获得的数据:
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
:
mask = poly2mask(vx, vy, numel(y), numel(x));
讨论了here此函数使用的算法。但是,如果您想使用不需要特殊工具箱的纯MATLAB方法,则可以改为使用inpolygon
:
[cx, cy] = meshgrid(x, y); % Generate a grid of x and y values
mask = inpolygon(cx, cy, vx, vy);
在这种情况下,只要其中心点位于多边形内,就会在掩模中包含像素。在这个特定的例子中,这两种方法产生相同的结果掩模,但它们并不总是由于它们判断是否包含像素的标准不同。
获取面具轮廓的坐标需要更多一些,围绕周边进行适当排序。为了实现这一点,我们可以将掩模表示为一系列顶点和三角形面(使用triangulation
函数),然后计算free boundary(即仅存在于一个三角面上的边): / p>
% 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
我们可以这样绘制:
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);
xOutline
和yOutline
中的轮廓坐标从围绕遮罩区域逆时针方向的绿色圆圈开始排序。
答案 1 :(得分:1)
似乎你需要任何行光栅化算法(给出近似线段的整数网格点的坐标)。
考虑Bresenham algortihm或DDA。