OpenCV中文网站例程——直线拟合cvFitline

转自:http://buaagc.blog.163.com/blog/static/72788394201211314450348/

OpenCV中 CvSeq 对象由以下语句生成

 //创建 CvSeq的容器对象

  CvMemStorage* storage = cvCreateMemStorage(0);

  // 创建 CvSeq对象

  // 第一个参数  生成后的序列的标志( 不甚解)

  // 第二个参数 队列(Sequence)头的Size

  // 第三个参数  节点的Size

  // 第四个参数  存储CvSeq的容器对象

 CvSeq* point_seq = cvCreateSeq( CV_32FC2, sizeof(CvSeq),sizeof(CvPoint2D32f), storage );

 

用完后,以下列形式释放内存

 cvClearSeq(point_seq);

 cvReleaseMemStorage(&storage);

 

向CvSeq中添加数据时:

cvSeqPush(point_seq, &cvPoint2D32f(x坐标,y坐标));

 FitLine函数的用法:

// 二维空间点拟合时 是 float[4]

// 三位空间点拟合时 是 float[6]

float *line = new float[4];

 // 第一个参数: 存储点序列

// 第二个参数: 拟合算法,其中 CV_DIST_L2 就是平常的最小二乘法

// 第三,第四,第五参数推荐值是0,   0.01,  0.01,

// 第六参数: line中存储返回值

// 二维空间时: line[0--3] 分别为 (vx, vy,x0, y0)

//     其中 vx, vy 是正规化之后的斜率向量。 x0,y0 是直线经过的点。

// 三维空间时:line[0--5]  分别是 (vx, vy,vz, x0, y0, z0) 。意义同上

cvFitLine(point_seq,CV_DIST_L2,0,0.01,0.01,line);


 拟合程序::

 #include <cv.h>

#include <stdio.h>

#include <math.h>

float myLinearity(CvSeq *);

int main(void)

{

int i;

double fx[] = {0.0, 0.301, 0.477, 0.602,0.699, 0.778, 0.845, 0.903, 0.954, 1.0};

double fy[] = {3.874, 3.202, 2.781, 2.49,2.274, 2.156, 1.934, 1.74, 1.653, 1.662};

float *line = new float[4];

float linearity=0.0f;

//Sequence的容器


CvMemStorage* storage = cvCreateMemStorage(0);

//三维空间的话,把CV_32FC2改为CV_32FC3、 把CvPoint2D32f 改为CvPoint3D32f

CvSeq* point_seq = cvCreateSeq( CV_32FC2,sizeof(CvSeq), sizeof(CvPoint2D32f), storage );

for (i=0; i<10; i++){

//向Sequence中追加元素

cvSeqPush(point_seq,&cvPoint2D32f(fx[i],fy[i]));

}

linearity = myLinearity(point_seq);

cvFitLine(point_seq,CV_DIST_L2,0,0.01,0.01,line);

fprintf(stdout,"v=(%f,%f),vy/vx=%f,(x,y)=(%f,%f),Linearity=%f/n",line[0],line[1],line[1]/line[0],line[2],line[3],linearity);

cvClearSeq(point_seq);

cvReleaseMemStorage(&storage);

delete line;

return 0;

}

 

//计算直线拟合度

float myLinearity(CvSeq *seq)

{

int i;

CvPoint2D32f *p;

float *x = new float[seq->total];

float *y = new float[seq->total];

float x_bar=0.0, y_bar=0.0;

float u11=0.0, u20=0.0, u02=0.0;

float linearity=0.0;

 

for (i=0; i < seq->total; i++){

p=(CvPoint2D32f*)cvGetSeqElem(seq,i);

x[i]=p->x;

y[i]=p->y;

}

//x_bar, y_bar

for (i=0; i < seq->total; i++){

x_bar+=x[i];

y_bar+=y[i];

}

x_bar/=seq->total;

y_bar/=seq->total;

 

for (i=0; i < seq->total; i++){

u11+=((x[i]-x_bar)*(y[i]-y_bar));

u20+=pow(x[i]-x_bar,2.0f);

u02+=pow(y[i]-y_bar,2.0f);

}

u11/=seq->total;

u20/=seq->total;

u02/=seq->total;

 

//计算直线度

linearity =sqrt(4*pow(u11,2.0f)+pow(u20-u02,2.0f))/(u20+u02);

delete x;

delete y;

return linearity;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV中,可以使用cv::fitLine函数来进行直线拟合。该函数通过最小化每个点到直线的距离总和来拟合直线。可以选择不同的距离函数,其中欧几里得距离是最常用的距离函数,对应于标准的最小二乘线拟合。如果点集中包含异常值,可以选择其他异常点影响较小的距离函数。cv::fitLine函数还可以用于将一组3D点集拟合为一条直线,输入为cv::Point3i或cv::Point3f类型的数据,输出类型为std::Vec6f。\[1\] 要进行直线拟合,首先需要将点的坐标插入到std::vector<cv::Point>中。可以使用双循环来迭代像素,将非零像素点的坐标插入到vector中。\[2\] 在提取可能的点集后,可以使用cv::fitLine函数进行直线拟合。可以在黑色图像上绘制一条白线,并将其与用于检测线条的Canny轮廓图像相交,以提取探测到的第一条线段的轮廓像素。\[3\] 综上所述,要在OpenCV中进行直线拟合,可以使用cv::fitLine函数,并将点的坐标插入到std::vector<cv::Point>中。 #### 引用[.reference_title] - *1* *2* *3* [OpenCV实战系列——拟合直线](https://blog.csdn.net/m0_58523831/article/details/129660972)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值