我在某些C代码中遇到问题,我认为它属于数学交换。
我有一个由用户拖动鼠标生成的x和y位置的变化数组,我如何确定是否绘制了一条直线。
我目前正在使用线性回归,有更好(更有效)的方法吗?
修改 Hough转型尝试:
#define abSIZE 100
#define ARRAYSIZE 10
int A[abSIZE][abSIZE]; //points in the a-b plane
int dX[10] = {0, 10, 13, 8, 20, 18, 19, 22, 12, 23};
int dY[10] = {0, 2, 3, 1, -1, -2, 0, 0, 3, 1};
int absX[10]; //absolute positions
int absY[10];
int error = 0;
int sumx = 0, sumy = 0, i;
//Convert deltas to absolute positions
for (i = 0; i<10; i++) {
absX[i] = sumx+=dX[i];
absY[i] = sumy+=dY[i];
}
//initialise array to zero
int a, b, x, y;
for(a = -abSIZE/2; a < abSIZE/2; a++) {
for(b = -abSIZE/2; b< abSIZE/2; b++) {
A[a+abSIZE/2][b+abSIZE/2] = 0;
}
}
//Hough transform
int aMax = 0;
int bMax = 0;
int highest = 0;
for(i=0; i<10; i++) {
x = absX[i];
y = absX[i];
for(a = -abSIZE/2; a < abSIZE/2; a++) {
for(b = -abSIZE/2; b< abSIZE/2; b++) {
if (a*x + b == y) {
A[a+abSIZE/2][b+abSIZE/2] += 1;
if (A[a+abSIZE/2][b+abSIZE/2] > highest) {
highest++; //highest = A[a+abSIZE/2][b+abSIZE/2]
aMax = a;
bMax = b;
}
}
}
}
}
printf("Line is Y = %d*X + %d\n",aMax,bMax);
//Calculate MSE
int e;
for (i = 0; i < ARRAYSIZE; i++) {
e = absY[i] - (aMax * absX[i] + bMax);
e = (int) pow((double)e, 2);
error += e;
}
printf("error is: %d\n", error);
答案 0 :(得分:2)
虽然线性回归听起来像是解决任务的一种非常合理的方式,但这里有另一个建议:Hough transform,它可能对异常值更有效。这是一个如何应用的粗略草图:
A
(x, y)
(例如,以(0,0)开头)a
和b
,a*x + b = y
。所有这些点(a,b)在a-b平面中定义一条直线A
中相应的单元格,代表量化平面A
中找到一个最大值,它将对应于xy平面中由原点支持最多的直线的参数(a, b)
更多细节,例如这里:
http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MARSHALL/node32.html
编辑:这是来自维基百科的一句话,它解释了为什么最好使用不同的参数化来处理垂直线(a
在ax+b=y
中将变为无限):
但是,垂直线条会造成问题。它们更自然地被描述为x = a并且将产生斜率参数m的无界值。因此,出于计算原因,Duda和Hart提出使用一对不同的参数,表示为
r
和theta
,用于霍夫变换中的线。这两个值结合使用,定义了极坐标。
感谢Zaw Lin指出这一点。