【问题标题】:Recognizing edges based on points and normals基于点和法线识别边缘
【发布时间】:2010-08-15 21:59:33
【问题描述】:

我在根据相对法线对点进行分类时遇到了一点问题。 我想做的是使用我在下面获得的信息将简化的多边形拟合到点,并在一定程度上偏向 90 度角。

我有每个点的粗略(虽然不是很准确)法线,但我不确定如何根据点的接近程度和法线的接近程度来分离数据库。我计划在对每个人脸的点进行分块后进行线性回归,因为法线有时与实际人脸不太吻合(尽管每个人脸彼此接近)

示例: alt text http://a.imageshack.us/img842/8439/ptnormals.png

理想情况下,我希望能够在此数据周围放置一个矩形。但是,多边形不必是凸的,也不必与轴对齐。

任何有关如何实现此类目标的提示都很棒。

提前致谢

【问题讨论】:

  • 我不知道这样的“官方方式”解决了,但不会“测量”3个连续点之间的角度并找到最接近90度的角度,给你边缘点(中间的那个)?
  • 一个有趣的例子,顺便说一句。我喜欢它。
  • 虽然有时会有一些噪音,并且您可能有一个点与其他两个点成 90 度角,但通常会拟合成一条直线:\
  • 哦,好吧,正如我所说,我不知道“官方”方式。我不记得了。但是,仍然,如果你总是拟合一个矩形,你总是可以选择最远的点作为正确的点(结果是 4 个点 - 如果你得到一个噪声点,那一个不会“生存”该标准)。
  • 矩形是凸的!所以使用凸包然后矩形它:)

标签: algorithm matlab pattern-matching computational-geometry


【解决方案1】:

我不确定这是否是您正在寻找的,但这是我解决问题的尝试,因为我理解它:

我正在使用法线向量的角度来查找属于矩形每一边(左、右、上、下)的点,然后简单地为每个点拟合一条线。

%# create random data (replace those with your actual data)
num = randi([10 20]);
pT = zeros(num,2);
pT(:,1) = rand(num,1);
pT(:,2) = ones(num,1) + 0.01*randn(num,1);
aT = 90 + 10*randn(num,1);

num = randi([10 20]);
pB = zeros(num,2);
pB(:,1) = rand(num,1);
pB(:,2) = zeros(num,1) + 0.01*randn(num,1);
aB = 270 + 10*randn(num,1);

num = randi([10 20]);
pR = zeros(num,2);
pR(:,1) = ones(num,1) + 0.01*randn(num,1);
pR(:,2) = rand(num,1);
aR = 0 + 10*randn(num,1);

num = randi([10 20]);
pL = zeros(num,2);
pL(:,1) = zeros(num,1) + 0.01*randn(num,1);
pL(:,2) = rand(num,1);
aL = 180 + 10*randn(num,1);

pts = [pT;pR;pB;pL];                 %# x/y coords
angle = mod([aT;aR;aB;aL],360);      %# angle in degrees [0,360]

%# plot points and normals
plot(pts(:,1), pts(:,2), 'o'), hold on
theta = angle * pi / 180;
quiver(pts(:,1), pts(:,2), cos(theta), sin(theta), 0.4, 'Color','g')
hold off

%# divide points based on angle
[~,bin] = histc(angle,[0 45 135 225 315 360]);
bin(bin==5) = 1;                     %# combine last and first bin

%# fit line to each segment
hold on
for i=1:4
    %# indices of points in this segment
    idx = ( bin == i );

    %# x/y or y/x
    if i==2||i==4, xx=1; yy=2; else xx=2; yy=1; end

    %# fit line
    coeff = polyfit(pts(idx,xx), pts(idx,yy), 1);
    fit(:,1) = 0:0.05:1;
    fit(:,2) = polyval(coeff, fit(:,1));

    %# plot fitted line
    plot(fit(:,xx), fit(:,yy), 'Color','r', 'LineWidth',2)
end
hold off

【讨论】:

  • 感谢 Amro 的回答。我不确定我是否描述得足够好,但我的数据并不仅限于矩形,它们的表现也不是很好。
  • @Xzhsh:上面的解决方案并不是真的要拟合一个矩形,更像是 4 个线段,每个线段由具有特定法线方向的点确定。也许你应该准确描述一下你期待的结果;根据您发布的数字,这些点几乎形成了一个矩形。
  • 根据我发布的图,我确实想得到一个矩形,但我可能不清楚我的数据的性质。因为它是屋顶的激光雷达数据,所以我可以得到三角形、八边形或任何类型的多边形。我不能真正将结果集限制为四边形:\。就是说,您的答案中的某些线条确实对我有所帮助(当我有一条垂直线时,我一直坚持使用垂直线),所以非常感谢您的帮助!
【解决方案2】:

我会尝试以下方法

  1. 根据接近度和相似角度对点进行聚类。我会使用单链接层次聚类(Matlab 中的LINKAGE),因为你不知道先验会有多少边。单连杆有利于线性结构,这正是您正在寻找的。作为两点之间的距离标准,您可以使用点坐标之间的欧几里得距离乘以角度的函数,当角度相差超过 20 度或 30 度时,角度会急剧增加。
  2. 对数据进行(稳健)线性回归。使用法线可能有帮助,也可能没有帮助。我的猜测是他们不会有太多帮助。为简单起见,您最初可能希望忽略法线。
  3. 找到线之间的交点。
  4. 如果必须这样做,您可以随时尝试改进拟合,例如将相反的线限制为平行。

如果失败,您可以尝试实现THIS PAPER 中的方法,它允许一次拟合多条直线。

【讨论】:

  • 谢谢,这看起来像我要找的。星期天我没时间在实验室工作,但我明天试试,然后回复你。再次感谢!
【解决方案3】:

您可以获取每边 X 和 Y 坐标的平均值,然后根据该平均值制作线条。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多