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]),当然能唯一确定一条直线。
#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]),当然能唯一确定一条直线。
相关文章推荐
- opencv——利用轮廓信息画斜矩形、外接圆、拟合直线等
- OpenCV 直线拟合
- OpenCV2编程手册笔记之 7.4用直线拟合一组点
- opencv之7.4用直线拟合一组点
- OpenCV—直线拟合fitLine
- 基于opencv的直线和曲线拟合与绘制(最小二乘法) (待测试)
- 【算法+OpenCV】基于opencv的直线和曲线拟合与绘制(最小二乘法)
- 《OpenCV》Part6 OpenCV3.1.0 用直线拟合图像中的物体
- 最小二乘法拟合直线 C++/OpenCV
- 算法+OpenCV】基于opencv的直线和曲线拟合与绘制(最小二乘法)
- opencv之fitline直线拟合
- opencv中的直线拟合函数 cvFitLine
- matlab使用opencv (轮廓提取+直线拟合)
- OpenCV 直线拟合及应用
- 基于OpenCV的图像直线分析和拟合工具
- OpenCV 学习(直线拟合)
- opencv直线拟合
- OpenCV_(Fit Line with points)用直线拟合一组点
- OpenCV 直线拟合
- [OpenCV]直线拟合