# ransac 算法原理介绍与实现

2011/12/01 16:26

ransac是RANdom SAmple Consensus的简称，它是根据一组包含异常数据的样本数据集，通过迭代的方法计算出数据的数学模型参数，得到有效样本数据的非确定性的算法。它于1981年由 Fischler和Bolles最先提出。

void Ransac(IplImage *pload,IplImage *pnew,int *x_cord,int *y_cord,int length, double &c0,double &c1,double &c2,char *file_name_prefix2,int nums,int &min)
{
int *count = new int[RANSAC_TIMES]; //计数
memset(count,0x00,sizeof(int)*RANSAC_TIMES);
CvMat  mat_x, mat_b, mat_c;
double  p_mat_x[9], p_mat_b[3],p_mat_c[3];//要转化成数组
min = length; //求最小值用
int flag_linear =0;
int position = 0; //记录误差最小的位置

double a =0,b=0,c =0;
for(int i =0; i<RANSAC_TIMES; i++)
{
int randnums[3];
int n = 0;

for (int t=0;t<3;t++)
{
n = rand() % length;
randnums[t] = n;
p_mat_x[t*3] = 1.0;
p_mat_x[t*3+1] = x_cord[n];
p_mat_x[t*3+2] = x_cord[n] * x_cord[n];

p_mat_b[t] = y_cord[n];
p_mat_c[t] = 0;
}

flag_linear = cvSolve(&mat_x, &mat_b, &mat_c,CV_LU);
if ( flag_linear == 0)
{
continue;
}
double *temp = mat_c.data.db;  //结果保存下来。
c = temp[0];   //常数项   //保留第i次结果
b = temp[1];   //一次项
a = temp[2];   //平方项
if (c2 < 0)
{
c2 = -c2;
}
double y_value = 0;
double x_square = 0;
int y_floor = 0;

double dis_error = 0;

for (int j=0;j<length;j++)
{
dis_error = fabs(y_cord[j] - ( a*(x_cord[j]*x_cord[j]) + b*x_cord[j] + c ));
if ( dis_error > RANSAC_THRESHOLD)
{
count[i]++;
}
}

if (min > count[i])
{
min = count[i];
position = i;
c0 = c;
c1 = b;
c2 = a;
}

}   //50次循环结束。

double x_square = 0;
double y_value = 0;
int y_floor = 0;
int pixelposition;
for (int x=0; x<pnew->width; x++)   //自变量取值范围
{
x_square = pow(double(x),2);
y_value = c2*x_square + c1*x + c0;
y_floor = cvFloor((y_value));

if ( y_floor >= 0 && y_floor < pnew->height )
{
((uchar*)(pnew->imageData + pnew->widthStep*y_floor))[3*x]=255;
((uchar*)(pnew->imageData + pnew->widthStep*y_floor))[3*x+1]=0;
((uchar*)(pnew->imageData + pnew->widthStep*y_floor))[3*x+2]=0;
}
for (int y=0;y<pnew->height;y++)
{
pixelposition = y*step+x;
{
((uchar*)(pnew->imageData + pnew->widthStep*y))[3*x]= 0;
((uchar*)(pnew->imageData + pnew->widthStep*y))[3*x+1]=0;
((uchar*)(pnew->imageData + pnew->widthStep*y))[3*x+2]=255;
}
}
}

delete []count;
cvSaveImage(file_name_prefix2,pnew);

}

0
1 收藏

2016/02/25 20:56

2011/12/26 17:04

2011/12/24 13:17

3 评论
1 收藏
0