一、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。
其实该画图算法尚存在缺陷,那就是不能控制迭代方向,即画椭圆无法控制顺时针或逆时针,各位如果有什么好的想法欢迎留言,我们可以一起讨论学习!!!
实现代码:点击打开链接