OpenCV2入门——core组件之基础画图与算法实现

一、OpenCV基础画图函数介绍

1、画直线函数

CV_EXPORTS_W void line(CV_IN_OUT Mat&img, Point pt1, Point pt2, const Scalar&color, int thickness=1, int lineType=8, int shift=0);

1)img:输入输出图像,在该图像上画直线;

2)pt1、pt2:直线的起始点与终止点;

3)color:直线的颜色;

4)thickness:直线的粗细,默认值为1。

2、画圆函数

CV_EXPORTS_W void circle(CV_IN_OUTMat& img, Point center, int radius, const Scalar& color, intthickness=1, int lineType=8, int shift=0);

1)img:输入输出图像,在该图像上画图;

2)center:为圆心坐标;

3)radius:圆的半径;

4)color:圆的颜色;

5)thickness:圆的粗细,默认值为1,负数填充;

6)lineType:画线类型,默认8连通;

3、画椭圆函数

CV_EXPORTS_W void ellipse(CV_IN_OUTMat& img, Point center, Size axes, doubleangle, double startAngle, double endAngle, constScalar& color, int thickness=1, int lineType=8, intshift=0);

CV_EXPORTS_W void ellipse(CV_IN_OUT Mat& img, const RotatedRect&box, const Scalar& color, int thickness=1, int lineType=8);

1)img:输入输出图像,在该图像上画图;

2)center:为椭圆中心坐标;

3)axes:为椭圆尺寸;box:旋转矩形类;

4)angle:椭圆顺时针偏转角;

5)startAngle:椭圆起始点角度(顺时针算);

6)endAngle:椭圆终止点角度(顺时针算);

7)color:椭圆的颜色;

8)thickness:椭圆的粗细,默认值为1,负数填充;

9)lineType:画线类型,默认8连通;

4、画矩形函数

CV_EXPORTS_W void rectangle(CV_IN_OUTMat& img, Point pt1, Point pt2, constScalar& color, int thickness=1, int lineType=8, intshift=0);

CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec, constScalar& color, int thickness=1, int lineType=8, int shift=0);

1)img:输入输出图像,在该图像上画图;

2)rec:为矩形类;pt1、pt2:直线的起始点与终止点;

3)color:矩形的颜色;

4)thickness:矩形的粗细,默认值为1,负数填充;

5)lineType:画线类型,默认8连通;

5、画多边形函数

CV_EXPORTS void polylines(Mat& img, const Point** pts, constint* npts, intncontours, bool isClosed, const Scalar& color, intthickness=1, int lineType=8, int shift=0 );

CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts, bool isClosed, constScalar& color, int thickness=1, int lineType=8, intshift=0 );

1)img:输入输出图像,在该图像上画图;

2)pts:多边形顶点集;

3)isClosed:是否闭合标志符;

4)color:多边形的颜色;

5)thickness:多边形的粗细,默认值为1;

6)lineType:画线类型,默认8连通;

填充多边形:

CV_EXPORTS void fillPoly(Mat& img, const Point** pts, const int* npts,int ncontours, const Scalar& color, int lineType=8, int shift=0, Pointoffset=Point() );

CV_EXPORTS_W voidfillPoly(InputOutputArray img, InputArrayOfArrays pts, constScalar& color, int lineType=8, int shift=0, Point offset=Point() );

 

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main()
{
	Mat src = Mat::zeros(400,400,CV_8UC1);
	if (src.empty())	return -1;

	line(src,Point(50,150),Point(100,50),Scalar(255),1);
	circle(src,Point(300,100),40,Scalar(255),-1,8);
	ellipse(src,Point(300,200),Size(30,40),45,0,360,Scalar(255),1);
	rectangle(src,Point(260,260),Point(340,340),Scalar(255),-1);

	vector<Point> polyPoints;
	polyPoints.push_back(Point(100,150));
	polyPoints.push_back(Point(150,200));
	polyPoints.push_back(Point(100,250));
	polyPoints.push_back(Point(50,200));
	polylines(src,polyPoints,true,Scalar(255),2);

	polyPoints.clear();
	polyPoints.push_back(Point(100,275));
	polyPoints.push_back(Point(150,325));
	polyPoints.push_back(Point(100,375));
	polyPoints.push_back(Point(50,325));
	vector<vector<Point>> ppa;
	ppa.push_back(polyPoints);
	fillPoly(src,ppa,Scalar(255));

	imshow("s",src);
	waitKey(0);

	return 0;
}

二、基于OpenCV的画图算法

其实画图函数的实现就两个步骤,先构造图形函数,然后选择画图方式。所以,后期可以从改进图形公式和画图算法两个方面着手。另外,画矩形和多边形的函数可由画直线算法组合,而画圆算法可由椭圆算法组合。

1、画直线算法

1)构造直线一般式:Ax+By+C=0(x1≤x≤x2或(y1≤y≤y2))

已知直线上的两点p1和p2,则可分为以下三种情况:

a)x1≠x2且y1≠y2:A=(y1-y2)/(x1-x2),B=-1,C=y1-A*x1;

b)x1=x2且y1≠y2:A=-1,B=0,C=x1=x2;

c)x1≠x2且y1=y2:A=0,B=-1,C=y1=y2;

2)画图方法一:全局扫描式

逐点扫描图片各点,坐标符合公式则可认为该点在直线上,且在两点之间。

3)画图方法二:逐点跟踪式

a)令指针指向起始点p1;

b)在其3*3(8连接)或上下左右(4连接)邻域内寻找最贴近该直线的一个点,指针指向该点;

c)重复以上两个步骤(注意排除前一个点),直到最后一个点p2。

2、画椭圆算法

1)构造椭圆标准方程:

已知椭圆中心坐标p( x0,y0 )、尺寸(即a、b)、偏转角angle、起始点角度startAngle和终止点角度endAngle(顺时针算)。

因椭圆需旋转angle,所以先把坐标系转为极坐标系,坐标映射后,根据椭圆标准公式和参数方程得出以下公式:

(因不知道如何插入WORD的公式或图片,所以用类似代码方式写出如下公式)

r = sqrt( x*x+y*y );
theta = atan2( y,x );
x' = r*cos( theta-angle );
y' = r*sin( theta-angle );

起始点坐标p1:

x1 = a*cos(startAngle);
y1 = b*sin(startAngle);
r = sqrt( x1*x1+y1*y1 );
theta = atan2( y1,x1 );
x1' = r*cos( theta-angle );
y1' = r*sin( theta-angle );

终止点坐标p2:

x2 = a*cos(endAngle);
y2 = b*sin(endAngle);
r = sqrt( x2*x2+y2*y2 );
theta = atan2( y2,x2 );
x2' = r*cos( theta-angle );
y2' = r*sin( theta-angle );

旋转并中心化后椭圆方程:x‘^2/a^2 + y'^2/b^2 = 1;

2)画图方法一:全局扫描式

逐点扫描图片各点,坐标符合公式则可认为该点在椭圆上,且在两点之间。

3)画图方法二:逐点跟踪式

a)令指针指向起始点p1;

b)在其3*3(8连接)或上下左右(4连接)邻域内寻找最贴近该椭圆的一个点,指针指向该点;

c)重复以上两个步骤(注意排除前一个点),直到最后一个点p2。

其实该画图算法尚存在缺陷,那就是不能控制迭代方向,即画椭圆无法控制顺时针或逆时针,各位如果有什么好的想法欢迎留言,我们可以一起讨论学习!!!

实现代码:点击打开链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值