根据点和法线识别边缘

时间:2010-08-15 21:59:33

标签: algorithm matlab pattern-matching computational-geometry

我根据相对法线对点进行分类有点问题。 我想要做的是使用我下面得到的信息来为点拟合一个简化的多边形,偏向90度角度。

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

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

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

关于如何实现这样的事情的任何暗示都会很棒。

提前致谢

3 个答案:

答案 0 :(得分:2)

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

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

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

plot

答案 1 :(得分:1)

我会尝试以下

  1. 根据接近度和类似角度对点进行聚类。我使用单链接层次聚类(Matlab中的LINKAGE),因为你不知道先验将会有多少条边。单连杆有利于线性结构,这正是您正在寻找的。作为两点之间的距离标准,您可以使用点坐标之间的欧氏距离乘以角度函数,一旦角度差异超过20或30度,就会非常陡峭地增加。
  2. 对数据进行(稳健)线性回归。使用法线可能会有所帮助,也可能没有帮助。我的猜测是他们不会帮助太多。为简单起见,您可能希望最初忽略法线。
  3. 找到线之间的交叉点。
  4. 如果必须,您可以尝试改善贴合度,例如将相对的线条约束为平行线。
  5. 如果失败,您可以尝试在THIS PAPER中实施该方法,这样可以同时拟合多条直线。

答案 2 :(得分:0)

你可以得到每一边的X和Y坐标的平均值,然后根据它来制作线条。

相关问题