您的位置:首页 > 运维架构

opencv拟合直线并在屏幕上绘出

2012-08-29 14:50 253 查看
#include "stdafx.h"

#include <cv.h>

#include <highgui.h>

#include <stdio.h>

#include <math.h>

int main()

{

 IplImage *img=cvCreateImage(cvSize(500,500),8,3);//开辟500×500的8位3通道的图像内存空间。

 CvRNG rng=CvRNG(-1);//产生随机数产生器的状态。

 cvNamedWindow("fitline",0);

 for (;;)

 {

  char key;

  int i;

  int count =cvRandInt(&rng)%100+1;//产生1~100之间的随机整数

  int outliers=count/5;//选取1/5数量的点作为outliers。

  float a=cvRandReal(&rng)*200;//产生0~1随机浮点数

  float b=cvRandReal(&rng)*40;

  float angle=cvRandReal(&rng)*CV_PI;//随机产生弧度

  float cos_a=cos(angle);

  float sin_a=sin(angle);

  CvPoint pt1 , pt2;

  CvPoint * points=(CvPoint*)malloc(count *sizeof(points[0]));

  CvMat pointMat=cvMat(1,count,CV_32SC2,points);

  float line[4];

  float d,t;

  b=MIN(a*0.3,b);

  //产生噪声点

  for (i=0;i<count-outliers;i++)//被噪声污染的直线上的点

  {

   float x=(cvRandReal(&rng)*2-1)*a;

   float y=(cvRandReal(&rng)*2-1)*b;

   points[i].x=cvRound(x*cos_a-y*sin_a+img->width/2);

   points[i].y=cvRound(x*cos_a+y*sin_a+img->height/2);

  }

  for (;i<count;i++)//异常点

  {

   points[i].x=cvRandInt(&rng) % img->width;

   points[i].y=cvRandInt(&rng) % img->height;

  }

  //拟合直线

  cvFitLine(&pointMat,CV_DIST_L1,1,0.001,0.001,line);

 

  cvZero(img);

  //画图

  for (i=0;i<count;i++)

  {

   cvCircle(img,points[i],2,(i<count-outliers)?CV_RGB(255,0,0):CV_RGB(255,255,0),

    CV_FILLED,CV_AA,0);

  }

       

  t=(float)(img->width+img->height);

  pt1.x=cvRound(line[2]-line[0]*t);//将直线上的点(line[2],line[3])沿直线移动一段距离

  pt1.y=cvRound(line[3]-line[1]*t);//将直线上的点(line[2],line[3])沿直线移动一段距离

  pt2.x=cvRound(line[2]+line[0]*t);//将直线上的点(line[2],line[3])沿直线移动一段距离

  pt2.y=cvRound(line[3]+line[1]*t);//将直线上的点(line[2],line[3])沿直线移动一段距离

  cvLine(img,pt1,pt2,CV_RGB(0,255,0),3,CV_AA,0);

  cvShowImage("fitline",img);

  key=(char)cvWaitKey(0);

  if (key==27||key=='q'||key=='Q')

   break;

  free(points);

 }

 cvDestroyWindow("fitline");

 cvReleaseImage(&img);

 return 0;

}

注意:

 (1):(line[0],line[1])不是直线上的点。它表示的是一个与拟合的直线平行的向量。且(line[0]*line[0]+line[1]*line[1]=1),所以直线的倾斜角度=asin(line[1])=acos(line[0])=atg(line[1]/line[0])。

(2):很明显,已知一个直线的方向(即向量)和直线上的一点(line[2],line[3]),当然能唯一确定一条直线。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  float include