OpenCV的vcFitLine函数

 

OpenCV的vcFitLine函数


以下代码是从文件中读取数据数据格式是,整形数据有空格分隔,然后用OpenCV曲线拟合显示:

[html]  view plain copy
  1. #include <stdio.h>  
  2. #include <cv.h>  
  3. #include <highgui.h>  
  4.   
  5. #pragma comment(lib, "cv.lib")  
  6. #pragma comment(lib, "cxcore.lib")  
  7. #pragma comment(lib, "highgui.lib")  
  8.   
  9. void put_data_into_array(CvPoint dataarray[], CvPoint data, int n)  
  10. {  
  11.     for(int i = 0; i < n - 1; i++)  
  12.         dataarray[i] = dataarray[i+1];  
  13.   
  14.     dataarray[n - 1] = data;  
  15. }  
  16.   
  17. int main(int argc, char* argv[])  
  18. {  
  19.     IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );  
  20.     cvNamedWindow( "fitline", 1 );  
  21.   
  22.     CvPoint pt1, pt2;   // 直线的两个端点  
  23.     CvPoint* points = (CvPoint*)malloc( 6 * sizeof(points[0])); // 存放随机产生的点点,数目为count  
  24.     CvMat pointMat = cvMat(1, 6, CV_32SC2, points); // 点集, 存储count个随机点points  
  25.     float line[4];      // 输出的直线参数。2D 拟合情况下,它是包含 4 个浮点数的数组 (vx, vy, x0, y0)  
  26.     //其中 (vx, vy) 是线的单位向量而 (x0, y0) 是线上的某个点  
  27.     float t;  
  28.   
  29.     FILE *fp = fopen("data.txt", "r");  
  30.     int v = 0;  
  31.   
  32.     while( !feof(fp) )  
  33.     {  
  34.         v++;  
  35.   
  36.         int x, y;  
  37.         fscanf(fp,"%d", &x);  
  38.         fscanf(fp,"%d", &y);  
  39.         put_data_into_array(points, cvPoint(x, y), 6);  
  40.         printf("[%d, %d]\n", x, y);  
  41.         if( v > 6 )  
  42.         {  
  43.   
  44.             // find the optimal line 曲线拟合  
  45.             cvFitLine(&pointMat, CV_DIST_L1, 1, 0.001, 0.001, line);   
  46.   
  47.             // 画出线段的两个端点(避免线太短,以线上一个随机点向两侧延伸line[0]*t )  
  48.             t = (float)(img->width + img->height) ;  
  49.             pt1.x = cvRound(line[2] - line[0] * t);  
  50.             pt1.y = cvRound(line[3] - line[1] * t);  
  51.             pt2.x = cvRound(line[2] + line[0] * t);  
  52.             pt2.y = cvRound(line[3] + line[1] * t);  
  53.             cvZero( img );  
  54.             cvLine(img, pt1, pt2, CV_RGB(0,255,0), 3, CV_AA, 0);  
  55.             cvCircle(img, cvPoint(x, y), 2,  CV_RGB(255, 0, 0), CV_FILLED, CV_AA, 0);  
  56.             char key = cvWaitKey(200);    
  57.             cvShowImage("fitline", img);  
  58.         }  
  59.     }  
  60.   
  61.     fclose(fp);  
  62.     free( points );  
  63.     cvWaitKey(-1);  
  64.   
  65.     cvDestroyWindow( "fitline" );  
  66.     cvReleaseImage(&img);  
  67.   
  68.     return 0;  
  69. }  

opencv中 2D 或 3D 点集的直线拟合

代码参考:

http://hi.baidu.com/yuzaihuan/item/283d12f260513b43922af269

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <cv.h>  
  3. #include <highgui.h>  
  4. #include <math.h>  
  5.   
  6. #pragma comment(lib, "cv.lib")  
  7. #pragma comment(lib, "cxcore.lib")  
  8. #pragma comment(lib, "highgui.lib")  
  9.   
  10. int main(int argc, char* argv[])  
  11. {  
  12.     IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );  
  13.     CvRNG rng = cvRNG(-1); //cvRNG()跟一般的C语言srand()使用方法一样,要先给它一个种子,  
  14.     //但srand()用到的是unsigned int的32位种子范围,而cvRNG()用的是64位长整数种子。  
  15.     //初始化CvRNG资料结构,假如seed给0,它将会自动转成-1   cvRNG(64位种子)  
  16.     cvNamedWindow( "fitline", 1 );  
  17.   
  18.     for(;;)  
  19.     {  
  20.         char key;  
  21.         int i;  
  22.         int count = cvRandInt(&rng)%100 + 1; //产生1-100 之间的数  
  23.         int outliers = count/5; // 奇异点的个数。0--20 之间的数  
  24.         printf("count = %d", count);  
  25.         float a = cvRandReal(&rng)*200;  // 0~ 199 之间的浮点数 [cvRandReal 浮点型随机数并更新 RNG ,范围在 0..1 之间,不包括 。  
  26.         float b = cvRandReal(&rng)*40; //返回0 ~ 39之间的数  
  27.         float angle = cvRandReal(&rng)*CV_PI;    
  28.         printf("count = %f", angle);  
  29.         float cos_a = cos(angle), sin_a = sin(angle);  
  30.         printf("cos_a = %f\n", cos_a);  
  31.   
  32.         CvPoint pt1, pt2; //直线的两个端点  
  33.         CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0])); //存放随机产生的点点,数目为count  
  34.         CvMat pointMat = cvMat( 1, count, CV_32SC2, points ); //点集, 存储count个随机点points  
  35.         float line[4]; //输出的直线参数。2D 拟合情况下,它是包含 4 个浮点数的数组 (vx, vy, x0, y0)  
  36.         //其中 (vx, vy) 是线的单位向量而 (x0, y0) 是线上的某个点  
  37.         float d, t;  
  38.         b = MIN(a*0.3, b);  
  39.   
  40.         // generate some points that are close to the line  
  41.         for( i = 0; i < count - outliers; i++ )  
  42.         {  
  43.             float x = (cvRandReal(&rng)*2-1)*a;  
  44.             float y = (cvRandReal(&rng)*2-1)*b;  
  45.             points[i].x = cvRound(x*cos_a - y*sin_a + img->width/2);  
  46.             points[i].y = cvRound(x*sin_a + y*cos_a + img->height/2);  
  47.         }  
  48.         // generate "completely off" points  
  49.         for( ; i < count; i++ )  
  50.         {  
  51.             points[i].x = cvRandInt(&rng) % img->width;  
  52.             points[i].y = cvRandInt(&rng) % img->height;  
  53.         }  
  54.   
  55.         // find the optimal line 曲线拟合  
  56.         cvFitLine(&pointMat, CV_DIST_L1, 1, 0.001, 0.001, line);   
  57.         cvZero( img );  
  58.   
  59.   
  60.         //画出产生的随机分布的点点  
  61.         for( i = 0; i < count; i++ )  
  62.         {  
  63.             cvCircle( img, points[i], 2, i < count - outliers ? CV_RGB(255, 0, 0) :CV_RGB(255,255,0), CV_FILLED, CV_AA, 0 );  
  64.         }  
  65.   
  66.         // ... and the long enough line to cross the whole image  
  67.         d = sqrt((double)line[0]*line[0] + (double)line[1]*line[1]);  //line[0 & 1]存储的是单位向量,所以d=1  
  68.         //printf("\n %f\n", d);  
  69.         line[0] /= d;  
  70.         line[1] /= d;  
  71.   
  72.         //画出线段的两个端点(避免线太短,以线上一个随机点向两侧延伸line[0]*t )  
  73.         t = (float)(img->width + img->height) ;  
  74.         pt1.x = cvRound(line[2] - line[0] * t);  
  75.         pt1.y = cvRound(line[3] - line[1] * t);  
  76.         pt2.x = cvRound(line[2] + line[0] * t);  
  77.         pt2.y = cvRound(line[3] + line[1] * t);  
  78.         cvLine( img, pt1, pt2, CV_RGB(0,255,0), 3, CV_AA, 0 );  
  79.   
  80.         cvShowImage( "fitline", img );  
  81.         key = (char) cvWaitKey(2000);  
  82.         if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC'  
  83.             break;  
  84.         free( points );  
  85.     }  
  86.   
  87.     cvDestroyWindow( "fitline" );  
  88.     return 0;  
  89. }  
[cpp]  view plain copy
  1. void cvFitLine( const CvArr* points, int dist_type, double param, double reps, double aeps, float* line );  

points 

2D 或 3D 点集,32-比特整数或浮点数坐标

dist_type 
拟合的距离类型 (见讨论).

param 
对某些距离的数字参数,如果是 0, 则选择某些最优值

reps, aeps 
半径 (坐标原点到直线的距离) 和角度的精度,一般设为0.01。

line 
输出的直线参数。2D 拟合情况下,它是包含 4 个浮点数的数组 (vx, vy, x0, y0),其中 (vx, vy) 是线的单位向量而 (x0, y0) 是线上的某个点.

对 3D 拟合,它是包含 6 个浮点数的数组 (vx, vy, vz, x0, y0, z0), 其中 (vx, vy, vz) 是线的单位向量,而 (x0, y0, z0) 是线上某点。


函数 cvFitLine 通过求 sumi:ρ(ri) 的最小值方法,用 2D 或 3D 点集拟合直线,其中 ri 是第 i 个点到直线的距离, ρ(r) 是下面的距离函数之一: 

dist_type=CV_DIST_L2 (L2): ρ(r)=r2/2 (最简单和最快的最小二乘法) 

dist_type=CV_DIST_L1 (L1): ρ(r)=r 

dist_type=CV_DIST_L12 (L1-L2): ρ(r)=2?[sqrt(1+r2/2) - 1] 

dist_type=CV_DIST_FAIR (Fair): ρ(r)=C2?[r/C - log(1 + r/C)], C=1.3998 

dist_type=CV_DIST_WELSCH (Welsch): ρ(r)=C2/2?[1 - exp(-(r/C)2)], C=2.9846 

dist_type=CV_DIST_HUBER (Huber): ρ(r)= r2/2, if r < C; C?(r-C/2), otherwise; C=1.345 


opencv中随机数的生成


产生标准正态分布的随机数或矩阵的函数

概念

1. 一般计算机的随机数都是伪随机数,以一个真随机数(种子)作为初始条件,然后用一定的算法迭代产生随机数序列。

2. 随机数的“种子”就是产生随机数的第一次使用值,机制是通过一个比较复杂函数,将这个种子的值映射到随机数空间的某一个点上,并且产生的随机数均匀地(或者符合正态分布等)散步在空间中,以后产生的随机数都与前一个随机数有关。

3. RNG : random number generation 随机数生成

(版权声明):参考网络

二、opencv中的函数

1. CvRNG cvRNG(int64 seed);
使用64位长整形种子,初始化随机数生成器状态。


cvGetTickCount();
返回64位长整形的时间数据,在opencv中是为CvRNG设置的专用种子。


2.  unsigned cvRandInt(CvRNG* rng);

返回均匀分布的随机32位无符号整型值,并更新RNG的状态 ; 使用模操作可以获得确定边界的整形数值。

3.  double cvRandReal(CvRNG* rng);

返回均匀分布的随即浮点数,范围在0-1(不含1),并更新RNG的状态。

4.  void cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2 );

用随机数填充数组,并更新RNG的状态
arr 输出数组
dist_type 分布类型: CV_RAND_UNI - 均匀分布 ; CV_RAND_NORMAL - 正态分布 或者 高斯分布
param1 分布的第一个参数。如果是均匀分布它是随机数范围的闭下边界。如果是正态分布它是随机数的平均值。
param2 分布的第二个参数。如果是均匀分布它是随机数范围的开上边界。如果是正态分布它是随机数的标准差。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值